我正在使用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”)也不起作用。
如何在身份验证回调后获取该变量?
答案 0 :(得分:19)
这不起作用的原因是因为您将状态作为对象而不是字符串传递。看起来护照并没有为您提供该值的字符串。如果你想通过状态参数传递一个对象,你可以这样做:
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在回答中指出,您可以访问回调state
对象中的req.query
参数。
我不确定编码应用程序状态并将其传递到state
param是一个好主意。 OAuth 2.0 RFC Section 4.1.1将状态定义为"不透明值"。它旨在用于CSRF protection。在授权请求和回调之间保留应用程序状态的更好方法可能是:
state
参数值(例如,cookie的哈希)state
作为标识符保留应用程序状态state
参数检索回调请求处理程序中的应用程序状态答案 1 :(得分:1)
使用Node.js v0.8.9对此进行简要测试,最终通过getAuthorizeUrl
库中的node-auth
方法格式化运行时配置的Google OAuth 2.0授权请求参数。此方法依赖于querystring.stringify
格式化重定向网址:
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);
}
使用您指定的状态参数在控制台中进行测试:
querystring.stringify({ state: { blah: 'test' }})
=> 'state='
作为一种变通方法,您可以尝试对对象进行JSON编码,或使用单个字符串来解决您的问题。然后,您可以通过state
访问回调请求处理程序中的req.query.state
。访问时请记得JSON.parse(req.query.state)
。