如何使用 OAuth 存储和发送带有 API 请求的授权令牌?

Posted

技术标签:

【中文标题】如何使用 OAuth 存储和发送带有 API 请求的授权令牌?【英文标题】:How do I store and send authorization tokens with API requests using OAuth? 【发布时间】:2018-06-29 23:32:32 【问题描述】:

我正在尝试设置我的应用程序,以便可以使用 Spotify API。他们的 API 需要一个授权令牌以及每个请求,并且这个令牌在每个用户会话中都不同。我已经使用“passport-spotify”模块(详情如下)成功实现了 OAuth2 登录,并拥有了我目前存储在我的数据库中的令牌。一旦它在数据库中,它也可以在我的 Redux 存储中使用。

有效的护照策略:

  const spotifyConfig = 
    clientID: process.env.SPOTIFY_CLIENT_ID,
    clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
    callbackURL: process.env.SPOTIFY_CALLBACK
  

  const strategy = new SpotifyStrategy(spotifyConfig, (accessToken, refreshToken, profile, done) => 
    const spotifyId = profile.id
    const name = profile.displayName
    const email = profile.emails[0].value

    User.find(where: spotifyId)
      .then(foundUser => (foundUser
        ? foundUser.update(accessToken, refreshToken).then(() => done(null, foundUser))
        : User.create(name, email, spotifyId, accessToken, refreshToken)
          .then(createdUser => done(null, createdUser))
      ))
      .catch(done)
  )

  passport.use(strategy)


router.get('/', passport.authenticate('spotify', scope: ['user-read-email'], showDialog: true))

router.get('/callback', passport.authenticate('spotify', 
  successRedirect: '/home',
  failureRedirect: '/login'
))

我目前坚持的是如何设置我的 API 请求,以便在每次调用时访问该令牌。 'spotify-web-api-node' 节点模块有一个 setCredentials 方法,但我不知道如何访问令牌。

半功能 API 调用(它发出 API 请求但给了我未经授权的 403):

const SpotifyWebApi = require('spotify-web-api-node');

const spotifyApi = new SpotifyWebApi();

spotifyApi.setCredentials(
  clientId: 'my client id',
  clientSecret: 'my client secret',
  redirectUri: 'http://localhost:8888/auth/spotify/callback',
  refreshToken: 'cant figure out how to properly include this',
  accessToken: 'and this.',
);


export function searchMetallica()
  return spotifyApi.searchArtists('Metallica')
  .then(function(data) 
    console.log(data.body);
  , function(err) 
    console.error(err);
  );

我希望这不是一个新手问题。提前致谢。

【问题讨论】:

【参考方案1】:

你很亲密!

在您的情况下,您需要将令牌传递给 Spotify 包装器上的 setAccessToken() 方法:

spotifyApi.setAccessToken(<youraccesstoken>);

您可以以类似的方式设置刷新令牌:

spotifyApi.setRefreshToken(<yourrefreshtoken>);

简单易懂!

但是,有一个问题。如果您在所有呼叫中使用此 spotifyApi,这将为所有这些呼叫设置相同的访问令牌!您需要确保为每个用户使用适当的访问令牌,以便用户 A 不能为用户 B 执行操作,反之亦然。

您可以通过简单地实例化 API 包装器并在用户登录时或在进行调用时设置访问令牌来解决此问题。例如,获取热门曲目的调用可能如下所示(为方便起见,使用 Express):

app.get('/myendpoint', function (request, response) 

  const loggedInSpotifyApi = new SpotifyWebApi();
  loggedInSpotifyApi.setAccessToken(request.access_token);

  // Get top tracks!
  loggedInSpotifyApi.getMyTopTracks()
    .then(function(data) 
      response.send(data.body);
    , function(err) 
      console.error(err);
    );   
);

这是一个完整的工作故障,显示了授权代码流程和 spotify-web-api-node:https://glitch.com/edit/#!/spotify-authorization-code

如果您有任何问题,请告诉我!

【讨论】:

如果你没有设置合适的用户scope/permissions,也会抛出403错误。 getMyTopTracks() 需要“用户顶部阅读” 但是,客户端如何访问 access_token 以在 API 请求中设置它? 是否真的需要为每个请求将访问令牌保存到数据库中,因为它已过期?它不能存储在内存中吗?看起来有点矫枉过正,但我​​不是专家。面临同样的问题。

以上是关于如何使用 OAuth 存储和发送带有 API 请求的授权令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中使用带有服务帐户的 gmail api 或 google Oauth 来发送邮件?

如何发送带有标头参数的 HTTP 请求?

oAuth令牌认证 - 使用相同的密钥

如何存储 Angular 前端使用的 OAuth1 令牌

带有 okta OAUTH 令牌身份验证的 Django Rest API

如何将 oauth2 令牌发送给客户端并存储它们?