Express 和 PassportJs - Google OAuth2.0 策略没有给我一个 req.user 对象
Express and PassportJs - Google OAuth2.0 strategy not giving me a req.user object
我正在为我们的应用程序设置一个身份验证路由,我似乎无法使用 sequelize 获得 PassportJs 的 Google oAuth 2.0 策略来给我一个 req.user 对象。下面是我的代码,我试图只剪掉相关部分:)
我的 app.js 是这样设置的:
//Dependencies
const creds = require('./credentials');
const express = require('express');
const bodyparser = require('body-parser');
const passport = require('passport');
const flash = require('connect-flash');
const Sequelize = require('sequelize');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const sequelize = new Sequelize(creds.mssqlAuth);
//Routes
const indexRouter = require('./routes/index');
const authRouter = require('./routes/auth');
//Init
const app = express
//View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000, secure : true }
}));
//Init middlewares
app.use(passport.initialize());
app.use(passport.session());
//Init Routes
app.use('/', indexRouter);
app.use('/auth', authRouter);
这是我的授权路线:
'use strict';
// Dependencies
const express = require('express');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const creds = require('../credentials');
const Models = require('../models');
const Sequelize = require('sequelize');
const sequelize = new Sequelize(creds.mssqlAuth);
//Init router
const router = express.Router();
//Winston logging - dev purposes only
const winston = require('winston');
//Authenticate with Google and get users data
passport.use(new GoogleStrategy({
clientID: creds.googleAuth.clientID,
clientSecret: creds.googleAuth.clientSecret,
callbackURL: 'http://localhost:3000/auth/callback'
},
function(accessToken, refreshToken, profile, done) {
Models.users.findOne({
where: {
email: profile.emails[0].value,
}
}).then( user =>{
if (user){
Models.user.update({
**Update existing user here...**
},
where: { **Update existing user here...**} })
.then( user =>{
return Models.users.findOne({
where: { email: profile.emails[0].value }
});
}).then(user =>{
return done(null, user);
}).catch(error => { return done(error, null)});
}
else if(!user){
//****For the sake of brevity - Same as above, only create the new user****//
}
}).catch(error => { return done(error, null)});
//Serialization
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Models.users.findOne({
where: { id: id }
})
.then(user => done(null, user))
.catch(error => done(error, null));
});
//Initial auth call to Google
router.get('/',
passport.authenticate('google', {
hd: 'ourDomain.com',
scope: ['email'],
prompt: 'select_account'
})
);
//Callback - Send user to index or back to auth screen
router.get('/callback',
passport.authenticate('google',
{ failureRedirect: '/auth',
successRedirect: '/' }
));
我似乎能够验证所有这些,我什至得到了一个写给我们用户的新用户 table。但是在我的索引路线中,我正在检查以确保 req.user 存在。它始终未定义,这会导致返回 auth 路由的循环。
我想知道这是否与在 //localhost 而不是实际服务器下设置有关?此代码旨在成为我们快速开展新项目的样板设置。
奇怪的是,这段代码似乎也向我们的会话 table 写入了 3 个单独的会话,每次都是 运行。我不确定这是一个不相关的问题,还是我们这里出现问题的原因。
有人指导吗?
这个问题的解决方案相当简单——我将我们的会话 cookie 设置为安全的
相关文档如下:
https://www.npmjs.com/package/express-session#cookiesecure
所需要的只是更改 app.js 代码:
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000, secure : true },
secure: true
}));
为此:
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000 }
}));
//****************************************//
//***** Note the lack of secure: true ****//
//****************************************//
这是因为 http 上的应用程序 运行(自其本地主机)。通过该设置,secure: true 可防止将 cookie 发送到 auth 路由内的反序列化函数。这使整个身份验证过程失败。在生产中,显然我们会更改我们的配置,但目前效果很好。
我希望这能在将来为某人节省一些时间,这是一行修复:)
我正在为我们的应用程序设置一个身份验证路由,我似乎无法使用 sequelize 获得 PassportJs 的 Google oAuth 2.0 策略来给我一个 req.user 对象。下面是我的代码,我试图只剪掉相关部分:)
我的 app.js 是这样设置的:
//Dependencies
const creds = require('./credentials');
const express = require('express');
const bodyparser = require('body-parser');
const passport = require('passport');
const flash = require('connect-flash');
const Sequelize = require('sequelize');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const sequelize = new Sequelize(creds.mssqlAuth);
//Routes
const indexRouter = require('./routes/index');
const authRouter = require('./routes/auth');
//Init
const app = express
//View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000, secure : true }
}));
//Init middlewares
app.use(passport.initialize());
app.use(passport.session());
//Init Routes
app.use('/', indexRouter);
app.use('/auth', authRouter);
这是我的授权路线:
'use strict';
// Dependencies
const express = require('express');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const creds = require('../credentials');
const Models = require('../models');
const Sequelize = require('sequelize');
const sequelize = new Sequelize(creds.mssqlAuth);
//Init router
const router = express.Router();
//Winston logging - dev purposes only
const winston = require('winston');
//Authenticate with Google and get users data
passport.use(new GoogleStrategy({
clientID: creds.googleAuth.clientID,
clientSecret: creds.googleAuth.clientSecret,
callbackURL: 'http://localhost:3000/auth/callback'
},
function(accessToken, refreshToken, profile, done) {
Models.users.findOne({
where: {
email: profile.emails[0].value,
}
}).then( user =>{
if (user){
Models.user.update({
**Update existing user here...**
},
where: { **Update existing user here...**} })
.then( user =>{
return Models.users.findOne({
where: { email: profile.emails[0].value }
});
}).then(user =>{
return done(null, user);
}).catch(error => { return done(error, null)});
}
else if(!user){
//****For the sake of brevity - Same as above, only create the new user****//
}
}).catch(error => { return done(error, null)});
//Serialization
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Models.users.findOne({
where: { id: id }
})
.then(user => done(null, user))
.catch(error => done(error, null));
});
//Initial auth call to Google
router.get('/',
passport.authenticate('google', {
hd: 'ourDomain.com',
scope: ['email'],
prompt: 'select_account'
})
);
//Callback - Send user to index or back to auth screen
router.get('/callback',
passport.authenticate('google',
{ failureRedirect: '/auth',
successRedirect: '/' }
));
我似乎能够验证所有这些,我什至得到了一个写给我们用户的新用户 table。但是在我的索引路线中,我正在检查以确保 req.user 存在。它始终未定义,这会导致返回 auth 路由的循环。
我想知道这是否与在 //localhost 而不是实际服务器下设置有关?此代码旨在成为我们快速开展新项目的样板设置。
奇怪的是,这段代码似乎也向我们的会话 table 写入了 3 个单独的会话,每次都是 运行。我不确定这是一个不相关的问题,还是我们这里出现问题的原因。
有人指导吗?
这个问题的解决方案相当简单——我将我们的会话 cookie 设置为安全的
相关文档如下: https://www.npmjs.com/package/express-session#cookiesecure
所需要的只是更改 app.js 代码:
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000, secure : true },
secure: true
}));
为此:
//Session config
app.use(session({
secret: 'this is a super secret session sign in string',
store: new SequelizeStore({
db: sequelize,
checkExpirationInterval: 15 * 60 * 1000,
expiration: 8 * 60 * 60 * 1000
}),
resave: true,
saveUninitialized: true,
cookie: { maxAge: 8 * 60 * 60 * 1000 }
}));
//****************************************//
//***** Note the lack of secure: true ****//
//****************************************//
这是因为 http 上的应用程序 运行(自其本地主机)。通过该设置,secure: true 可防止将 cookie 发送到 auth 路由内的反序列化函数。这使整个身份验证过程失败。在生产中,显然我们会更改我们的配置,但目前效果很好。
我希望这能在将来为某人节省一些时间,这是一行修复:)