护照认证回调挂起
Posted
技术标签:
【中文标题】护照认证回调挂起【英文标题】:Passport authentication callback hangs 【发布时间】:2015-12-13 16:44:21 【问题描述】:几个小时后,我试图自己解决这个问题,我到 SO 社区寻找一些光明。
我正在使用护照进行用户身份验证。根据文档,它已经在我的主 express.js 文件中初始化:
app.use(passport.initialize());
我有一个 index.js 文件,它以这种方式处理 facebook-passport
:
索引.js
'use strict';
import express from 'express';
import passport from 'passport';
import auth from '../auth.service';
let router = express.Router();
//this function is defined in the auth.service import but copied it here in case it's needed (the `signToken` is also defined in the service)
function setTokenCookie(req, res)
if (!req.user) return res.json(404, message: 'Something went wrong, please try again.');
var token = signToken(req.user._id, req.user.role);
res.cookie('token', JSON.stringify(token));
res.redirect('/');
router
.get('/', passport.authenticate('facebook',
scope: ['email', 'user_about_me'],
failureRedirect: '/login'
))
.get('/callback', passport.authenticate('facebook',
successRedirect: '/',
failureRedirect: '/login'
), setTokenCookie);
module.exports = router;
以这种方式在 index.js 中导入的 passport.js:
passport.js
import passport from 'passport';
import
Strategy as FacebookStrategy
from 'passport-facebook';
exports.setup = function(User, config)
passport.use(new FacebookStrategy(
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL
,
function(accessToken, refreshToken, profile, done)
User.findOne(
'facebook.id': profile.id
, (findErr, user) =>
if (findErr)
return done(findErr);
if (!user)
let userToSave = new User(
name: profile.displayName,
email: profile.emails[0].value,
role: 'user',
username: profile.username,
provider: 'facebook',
facebook: profile._json
);
userToSave.save((saveErr) =>
if (saveErr) done(saveErr);
return done(null, user);
);
else
return done(null, user);
);
));
;
这是目前发生的情况:
Facebook 登录提示 在 Facebook 中成功验证后,回调 (/auth/facebook/callback) 将按预期使用用户信息和令牌到达。 用户保存在带有预期字段的数据库中事情变得奇怪的地方:
保存用户后,done(null,user)
什么也不做。应用程序挂起回调,客户端一直等待响应。
中间件 setTokenCookie 永远不会被调用,所以问题肯定出在上一步。
我尝试过的:
将来自passport.js
的整个设置函数封装在一个 process.tick 中(发现有人使用它但没有解决问题)
在 User.findOne(...).exec().then(user => ...)
中使用带有 Promise 的 Mongoose
如果您需要更多信息,请随时提出。非常感谢任何帮助。
谢谢!
【问题讨论】:
你调用了 mongoose.connect() 吗? 是的:)。关于 Mongoose 的所有内容都按预期工作,用户要么已保存,要么从数据库中检索,但在这两种情况下,当 done(null, user) 被调用时,它都会挂起。 您如何确定 setTokenCookie 没有执行?你到处都有console.logs吗? 我迷上了节点调试,我也尝试过使用 console.log()。但无论如何,如果它被执行,我至少会得到一些回应。 这个你搞定了吗?我遇到了同样的问题,现在我无法入睡。 【参考方案1】:我看到我的代码有一些可能丢失的部分。你在使用passport.session()
中间件吗?还有serializeUser
和deserializeUser
函数?
passport.serializeUser(function(user, done)
//place user's id in cookie
done(null, user.id);
);
passport.deserializeUser(function(id, done)
//retrieve user from database by id
User.findById(id, function(err, user)
done(err, user);
);
);
【讨论】:
你好@cody。是的,我尝试使用passport.session()
并删除它并将 session: false
选项添加到 Passport 策略。关于那些函数,它们被调用了吗?有必要吗?
serializeUser
将在用户通过 facebook 成功登录后调用,以使 cookie 中的 user.id 可用于后续请求。 deserializeUser
用于这些后续请求,以允许您从数据存储中检索用户。我相信您想通过passport.session()
中间件在您的场景中使用它们。我很确定护照希望它们用于所有服务,除了您为每个请求发送凭据的服务(通常是 API)。【参考方案2】:
如果您像我一样是护照/快递的菜鸟,这可能会有所帮助:
检查您是否在护照逻辑中调用了 done():
passport.use(new twitchStrategy(
clientID: config.twitchID,
clientSecret: config.twitchSecret,
/*to be updated*/
callbackURL: config.callbackURL,
scope: "user_read"
,
function(accessToken, refreshToken, profile, done)
console.log(profile);
***return done();***
));
【讨论】:
以上是关于护照认证回调挂起的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose“创建”方法 - 没有回调吗? (使用护照和角度)