【问题标题】:How can I access OAuth's state parameter using Passport.js?如何使用 Passport.js 访问 OAuth 的状态参数?
【发布时间】:2012-12-09 14:04:19
【问题描述】:

我正在使用 Passport.js 进行身份验证,并且根据 Google's OAuth2 documentation,我正在传递一个状态变量:

app.get('/authenticate/googleOAuth', function(request, response) {
  passport.authenticate('google', {
    scope:
    [
      'https://www.googleapis.com/auth/userinfo.profile',
      'https://www.googleapis.com/auth/userinfo.email'
    ],
    state: { blah: 'test' }
  })(request, response);
});

但是,我以后似乎无法访问该变量:

passport.use(new googleStrategy(
{
    clientID: '...',
    clientSecret: '...',
    callbackURL: '...',
    passReqToCallback: true
},
function(request, accessToken, refreshToken, profile, done) {
  console.log('state: ' + request.query.state);
  login(profile, done);
}));

request.query.state 未定义。 request.param("state") 也不起作用。

身份验证回调后如何获取该变量?

【问题讨论】:

    标签: authentication passport.js


    【解决方案1】:

    这不起作用的原因是因为您将状态作为对象而不是字符串传递。似乎护照并没有为您确定该值。如果你想通过 state 参数传递一个对象,你可以这样做:

    passport.authenticate("google", {
      scope: [
        'https://www.googleapis.com/auth/userinfo.profile',
        'https://www.googleapis.com/auth/userinfo.email'
      ],
      state: base64url(JSON.stringify(blah: 'test'))
    })(request, response);
    

    正如 Rob DiMarco 在他的回答中指出的那样,您可以在回调 req.query 对象中访问 state 参数。

    我不确定编码应用程序状态并将其传递给state 参数是一个好主意。 OAuth 2.0 RFC Section 4.1.1 将状态定义为“不透明值”。它旨在用于CSRF protection。在授权请求和回调之间保留应用程序状态的更好方法可能是:

    1. 生成一些state参数值(例如cookie的哈希)
    2. 在发起授权请求之前以state作为标识符保持应用程序状态
    3. 使用从 Google 传回的 state 参数在回调请求处理程序中检索应用程序状态

    【讨论】:

    • 缺少 { } 状态:base64url(JSON.stringify({blah: 'text'}))
    【解决方案2】:

    使用 Node.js v0.8.9 对此进行简要测试,最终通过 node-auth 库中的 getAuthorizeUrl 方法格式化 Google OAuth 2.0 授权请求的运行时配置参数。此方法依赖querystring.stringify 来格式化重定向 URL:

    exports.OAuth2.prototype.getAuthorizeUrl= function( params ) {
      var params= params || {};
      params['client_id'] = this._clientId;
      params['type'] = 'web_server';
      return this._baseSite + this._authorizeUrl + "?" + querystring.stringify(params);
    }
    

    (以上复制自https://github.com/ciaranj/node-oauth/blob/efbce5bd682424a3cb22fd89ab9d82c6e8d68caa/lib/oauth2.js#L123)。

    使用您指定的状态参数在控制台中进行测试:

    querystring.stringify({ state: { blah: 'test' }}) => 'state='

    作为一种解决方法,您可以尝试对您的对象进行 JSON 编码,或使用单个字符串,这应该可以解决您的问题。然后,您可以通过req.query.state 在回调请求处理程序中访问state。访问时记得JSON.parse(req.query.state)

    【讨论】:

    • 为什么是scope?我想是querystring.stringify({ state: { blah: 'test' }}),对吧?
    猜你喜欢
    • 2019-11-09
    • 2018-10-12
    • 2012-08-28
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 2015-05-03
    • 2019-09-11
    • 1970-01-01
    相关资源
    最近更新 更多