Passport.js 和 Restify 的会话问题
Session issues with Passport.js and Restify
我正在尝试开发一个简单的概念验证,该验证将 Passport 的 Google 身份验证策略与 Restify 和 Bookshelf.js 结合使用。我希望这个简单的应用程序能够让我解析 /sessions/google 路由(调用 Google 身份验证)并在身份验证成功后重定向到 /sessions/googleReturn。对于这个简单的概念证明,请假设对应于 User 模型的 table 包含一条正在验证的用户的记录。
下面是我目前正在试验的代码。目前,此代码会在身份验证后导致无休止的重定向循环。如果我删除 /sessions/googleReturn 路由中的 'passport.authenticate('google', { failureRedirect: '/' })' 行,/sessions/googleReturn 但是解析 req.user returns 一个空对象。我猜我没有初始化会话或正确地将会话绑定到护照。护照方法中的 console.log 输出似乎被抑制了,这使得调试变得困难。如果我将 Restify/client-sessions 替换为 express/express-session,我的概念证明就有效了。我究竟做错了什么?提前致谢。
var restify = require('restify');
var sessions = require('client-sessions');
var passport = require('passport');
var GoogleStrategy = require('passport-google').Strategy;
var User = require('./models/user'); // Bookshelf model
var server = restify.createServer({ name: 'test-server' });
server
.use(sessions({
cookieName: 'user',
secret: 'topsecret',
duration: 365 * 24 * 60 * 60 * 1000}))
.use(passport.initialize())
.use(passport.session());
passport.serializeUser(function(user, done) {
console.log('serialize user:', user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log('deserialize user:', id);
new User({ id: id }).fetch({require: true}).then(function(user) {
done(null, user);
}).catch(function(err) {
done(err, null);
});
});
passport.use(
new GoogleStrategy({
returnURL: 'http://localhost:3000/sessions/googleReturn',
realm: 'http://localhost:3000'
},
function(identifier, profile, done) {
console.log('Hello from the verify callback', identifier, profile);
new User({ email: profile.emails[0].value }).fetch({require: true}).then(function(user) {
done(null, user);
}).catch(function(err) {
done(err, null);
});
}
));
server.listen(3000, function () {
console.log('%s listening at %s', server.name, server.url);
});
server.get('/', function(req, res, next) {
res.send(200, 'Hello from root route.');
return next();
});
server.get(
'/sessions/google',
passport.authenticate('google')
);
server.get(
'/sessions/googleReturn',
passport.authenticate('google', { failureRedirect: '/' }),
function(req, res, next) {
console.log('Session user data?', req.user);
res.send(200, 'Hello from Google auth return route.');
return next();
}
);
如果您看到来自 google auth 的响应,它表示 302 已临时移动。
此外 google openid 已被弃用并替换为 google-加号登录。
Google OpenID: https://developers.google.com/accounts/docs/OpenID
有一个 npm 模块 google - 如果您想使用,请加登录。
npm install passport-google-plus
https://www.npmjs.com/package/passport-google-plus
当我 运行 遇到这个问题时,我发现我需要确保 restify 已准备好解析查询参数。我的重定向循环消失了。
server = restify.createServer({ name: 'test-server' });
server.use(restify.queryParser());
如果您使用的是 restify,它的重定向功能会略有不同。您可以简单地添加一个覆盖,例如:
function patchRedir(){
return function( req, res, next ){
res.redirect = function( url ){
res.header( 'Location', url )
res.send( 302 )
}
return next()
}
}
server.get('/auth/facebook/callback', patchRedir(), passport.authenticate('facebook', { failureRedirect: '/login' }), ( req, res, next ) => {
// Successful
res.send( 200 )
})
client-sessions
包在 req
中设置了一个会话对象,其名称与会话 cookie 名称相同。它默认为 session
,这意味着 req.session
对象可用。我发现 passport.js(好吧,实际上 passport-oauth2
需要这样的对象)才能将用户保存到会话中。因此,通过更改 client-sessions
配置中的 cookieName
,您可以在 req
中为会话对象使用不同的密钥!
GoogleStrategy 使用 passport-oauth2
作为基础,您可以查看确实需要 req.session
的来源:
https://github.com/jaredhanson/passport-oauth2/blob/master/lib/state/session.js
我发现了两个解决方案:
- 或者使用
session
cookie 名称
做一个小的,"universal handler" 为你 restify 服务器并放置如果 after 你设置会话但是 before 你设置护照:
server.use((req, res, next) => {
req.session = req.your_cookie_name;
return next();
});
我正在尝试开发一个简单的概念验证,该验证将 Passport 的 Google 身份验证策略与 Restify 和 Bookshelf.js 结合使用。我希望这个简单的应用程序能够让我解析 /sessions/google 路由(调用 Google 身份验证)并在身份验证成功后重定向到 /sessions/googleReturn。对于这个简单的概念证明,请假设对应于 User 模型的 table 包含一条正在验证的用户的记录。
下面是我目前正在试验的代码。目前,此代码会在身份验证后导致无休止的重定向循环。如果我删除 /sessions/googleReturn 路由中的 'passport.authenticate('google', { failureRedirect: '/' })' 行,/sessions/googleReturn 但是解析 req.user returns 一个空对象。我猜我没有初始化会话或正确地将会话绑定到护照。护照方法中的 console.log 输出似乎被抑制了,这使得调试变得困难。如果我将 Restify/client-sessions 替换为 express/express-session,我的概念证明就有效了。我究竟做错了什么?提前致谢。
var restify = require('restify');
var sessions = require('client-sessions');
var passport = require('passport');
var GoogleStrategy = require('passport-google').Strategy;
var User = require('./models/user'); // Bookshelf model
var server = restify.createServer({ name: 'test-server' });
server
.use(sessions({
cookieName: 'user',
secret: 'topsecret',
duration: 365 * 24 * 60 * 60 * 1000}))
.use(passport.initialize())
.use(passport.session());
passport.serializeUser(function(user, done) {
console.log('serialize user:', user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log('deserialize user:', id);
new User({ id: id }).fetch({require: true}).then(function(user) {
done(null, user);
}).catch(function(err) {
done(err, null);
});
});
passport.use(
new GoogleStrategy({
returnURL: 'http://localhost:3000/sessions/googleReturn',
realm: 'http://localhost:3000'
},
function(identifier, profile, done) {
console.log('Hello from the verify callback', identifier, profile);
new User({ email: profile.emails[0].value }).fetch({require: true}).then(function(user) {
done(null, user);
}).catch(function(err) {
done(err, null);
});
}
));
server.listen(3000, function () {
console.log('%s listening at %s', server.name, server.url);
});
server.get('/', function(req, res, next) {
res.send(200, 'Hello from root route.');
return next();
});
server.get(
'/sessions/google',
passport.authenticate('google')
);
server.get(
'/sessions/googleReturn',
passport.authenticate('google', { failureRedirect: '/' }),
function(req, res, next) {
console.log('Session user data?', req.user);
res.send(200, 'Hello from Google auth return route.');
return next();
}
);
如果您看到来自 google auth 的响应,它表示 302 已临时移动。 此外 google openid 已被弃用并替换为 google-加号登录。
Google OpenID: https://developers.google.com/accounts/docs/OpenID
有一个 npm 模块 google - 如果您想使用,请加登录。
npm install passport-google-plus https://www.npmjs.com/package/passport-google-plus
当我 运行 遇到这个问题时,我发现我需要确保 restify 已准备好解析查询参数。我的重定向循环消失了。
server = restify.createServer({ name: 'test-server' });
server.use(restify.queryParser());
如果您使用的是 restify,它的重定向功能会略有不同。您可以简单地添加一个覆盖,例如:
function patchRedir(){
return function( req, res, next ){
res.redirect = function( url ){
res.header( 'Location', url )
res.send( 302 )
}
return next()
}
}
server.get('/auth/facebook/callback', patchRedir(), passport.authenticate('facebook', { failureRedirect: '/login' }), ( req, res, next ) => {
// Successful
res.send( 200 )
})
client-sessions
包在 req
中设置了一个会话对象,其名称与会话 cookie 名称相同。它默认为 session
,这意味着 req.session
对象可用。我发现 passport.js(好吧,实际上 passport-oauth2
需要这样的对象)才能将用户保存到会话中。因此,通过更改 client-sessions
配置中的 cookieName
,您可以在 req
中为会话对象使用不同的密钥!
GoogleStrategy 使用 passport-oauth2
作为基础,您可以查看确实需要 req.session
的来源:
https://github.com/jaredhanson/passport-oauth2/blob/master/lib/state/session.js
我发现了两个解决方案:
- 或者使用
session
cookie 名称 做一个小的,"universal handler" 为你 restify 服务器并放置如果 after 你设置会话但是 before 你设置护照:
server.use((req, res, next) => { req.session = req.your_cookie_name; return next(); });