【发布时间】:2015-07-18 17:38:00
【问题描述】:
我遇到了无法解决的问题。我正在使用nodejs开发一个应用程序,使用mongodb、expressjs和passportjs作为我的身份验证中间件。
我目前有 3 种策略:facebook、twitter 和 instagram。我想要实现的是,当用户第一次登录时,如果用户使用一种策略登录并使用另一种策略登录,则将配置文件保存到同一个 mongodb 用户文档中。
这是我的 auth/index.js:
require('./local/passport').setup(User, config);
require('./facebook/passport').setup(User, config);
require('./twitter/passport').setup(User, config);
require('./instagram/passport').setup(User, config);
var router = express.Router();
router.use('/local', require('./local'));
router.use('/facebook', require('./facebook'));
router.use('/twitter', require('./twitter'));
router.use('/instagram', require('./instagram'));
这是,例如,我的 auth/twitter/index.js
var router = express.Router();
router
.get('/', passport.authenticate('twitter', {
failureRedirect: '/',
session: false
}))
.get('/callback', passport.authenticate('twitter', {
failureRedirect: '/',
session: false
}), auth.setTokenCookie);
module.exports = router;
但是我如何将 mongodb _id 传递给这个 auth/twitter/passport.js 以便将其传递给 mongoose 查询并更新用户?像向 auth/twitter 发送 POST 并访问 req.user._id 之类的东西?我不知道该怎么做。
exports.setup = function (User, config) {
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;
var TwitterApi = require('twitter');
passport.use(new TwitterStrategy({
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: config.twitter.callbackURL
},
function(token, tokenSecret, profile, done) {
User.findOne({
'twitter.id_str': profile.id
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
user = new User({
role: 'user',
[...]
非常感谢。
编辑: 这就是我设置 cookie 的方式:
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('/');
}
还有signToken函数:
function signToken(id) {
return jwt.sign({ _id: id }, config.secrets.session, { expiresInMinutes: 60*24*30 });
}
为什么 req.user 和 req.session 在我的策略中总是空的?
EDIT2:
我想我可以在调用策略之前使用 auth.isAuthenticated() 函数将用户附加到请求。我所做的是这样的:
router
.get('/', auth.isAuthenticated(), passport.authenticate('twitter', auth.isAuthenticated, {
failureRedirect: '/',
session: false
}))
.get('/callback', auth.isAuthenticated(), passport.authenticate('twitter', {
failureRedirect: '/',
session: false
}), auth.setTokenCookie);
但现在我遇到了这个问题:
UnauthorizedError: No Authorization header was found
我对 auth/twitter 的请求来自 $window.location。这似乎没有将用户对象附加到请求中,因为当我使用 isAuthenticated() 进行 GET 或 POST 时,用户对象被正确传递。这是我的 isAuthenticated() 函数:
function isAuthenticated() {
return compose()
// Validate jwt
.use(function(req, res, next) {
// allow access_token to be passed through query parameter as well
if(req.query && req.query.hasOwnProperty('access_token')) {
req.headers.authorization = 'Bearer ' + req.query.access_token;
}
validateJwt(req, res, next);
})
// Attach user to request
.use(function(req, res, next) {
User.findById(req.user._id, function (err, user) {
if (err) return next(err);
if (!user) return res.send(401);
req.user = user;
next();
});
});
}
【问题讨论】:
标签: node.js mongodb passport.js