在身份验证代码中出现了一些问题,这些问题在年初之前一直运行良好,然后看起来似乎没有发生变化,我试图回归到以前的版本并找不到运气的原因。所以我正在寻找帮助修复现在存在的代码。
我正在使用nodejs v0.10.25 Passportjs通过Google和Facebook提供身份验证。我的包裹:
"config-multipaas": "^0.1.0",
"restify": "^2.8.3",
"googleapis": "~2.1.5",
"mocha": "~2.3.3",
"restify-redirect": "~1.0.0",
"sequelize": "~3.12.2",
"mysql": "~2.9.0",
"passport": "~0.3.2",
"passport-facebook": "~2.0.0",
"passport-local": "~1.0.0",
"passport-google-oauth": "~0.2.0",
"sendgrid-webhook": "0.0.4",
"sendgrid": "~2.0.0",
"restify-cookies": "~0.2.0"
两周前,在处理应用程序的另一部分时,我注意到用户注册功能不再适用于任何一种服务。具体而言,Google Oauth2代码在初始同意页面后返回以下错误。
- 这是一个错误。
醇>错误:invalid_request
缺少必需参数:范围
以下是我的战略定义的相关部分:
passport.use(new FacebookStrategy({
clientID: siteConfigs.facebook.clientId,
clientSecret: siteConfigs.facebook.clientSecret,
callbackURL: authRoot + 'facebook/callback',
profileFields: ['id','name','emails', 'picture', 'location', 'birthday', 'gender']
},
function(accessToken, refreshToken, profile, done){...}
passport.use(new GooglePlusStrategy({
clientID: siteConfigs.google.clientId,
clientSecret: siteConfigs.google.clientSecret,
callbackURL: authRoot + 'google/callback',
profileFields: ['id','name','emails', 'gender', 'placesLived']
},
function(accessToken, refreshToken, profile, done){...}
令牌回调函数的机制不相关,因为进程永远不会那么远(由节点调试器和控制台日志语句验证)。
这是我的休息终点:
app.get('/auth/facebook', passport.authenticate('facebook', { session: false, scope: ['email']}));
app.get('/auth/google', passport.authenticate('google',
{
scope: ['profile', 'email'],
accessType: 'online',
session: false
})
);
app.get('/auth/:service/callback', function(req, res, next){
console.log('Request:', req.path(), req.getQuery());
passport.authenticate(req.params.service,
function(err, user, info){
var returnPath = '/html/authcallback.html';
if(err)
return res.redirect({
pathname: returnPath,
query: {
error: err
}
}, next);
else
return res.redirect({
pathname: returnPath,
query: {
id: user.id,
created: info
}
}, next);
})(req, res, next);
});
经过一些初步的故障排除后,我采用了Google的Oauth 2.0 Playground,使用自定义身份验证和令牌端点(我的passportjs版本中使用的端点)和我自己的客户端ID和密码来比较那里的每次互动和我的代码是什么这样做。对同意提示的初始请求正常工作并与Playground匹配,并且回调返回适当的代码,例如code=4/EUnaIvWpLIiHnKUR9WctOJKQ-_iWZ3_H9YeUYx7bJSo
。但是交换令牌代码的请求失败了。使用节点调试器来评估passport-google-oauth为令牌发回的重定向请求,它构建的URL是:
https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=http://localhost:8080/auth/google/callback&client_id=<ID>
将此与Google Oauth 2.0 Playground的可比较请求进行比较,结果如下:
http://www.googleapis.com?code=4/9uaUYjeExmPftgRLsRZ8MCc2e_7YGHow7kvew6Fkypo&redirect_uri=https://developers.google.com/oauthplayground&client_id=<ID>&client_secret=<SECRET>&scope=&grant_type=authorization_code
我的查询字符串中缺少几个参数,其中最重要的两个是我的代码和密码。我原以为Google的服务会为那些人返回错误。相反,它会为缺少的范围参数返回一个错误,而这个参数实际上在此过程中不需要此步骤(我不知道为什么操场应用程序包含它)。
最后,我非常肯定,随着Facebook战略开始失败,它也在我身边。在获得同意之后,使用多个代码返回我的回调是很奇怪的,然后最终返回TOO_MANY_REDIRECTS错误。
那么,有人有什么想法吗?再一次,这个相同的代码一直在工作到年初,然后开始失败一段时间。
答案 0 :(得分:1)
似乎在初始化服务器后我遗漏了以下代码:
api.use(restify.plugins.queryParser({ mapParams: false }));
一旦我添加该行,我就不会再看到Google错误,并且该过程会传回我的代码。