node.js - 角度与快递,会话不是持久的。每个请求都会创建一个新会话
问题描述
原始问题
我正在使用 passport.js 进行快速身份验证,当我在护照策略中使用 req.flash('message', 'message content') 时,闪现的信息不是在正常会话下而是在“会话”下,当我尝试使用 req.flash() 检索闪烁的消息,它是一个空数组。
我打印出 req ,它看起来像这样:
MemoryStore {
_events:
{ disconnect: [Function: ondisconnect],
connect: [Function: onconnect] },
_eventsCount: 2,
_maxListeners: undefined,
sessions:
{ gzNcx9b8rcWfDtJm03VnNJfhsNW8EJ7B:
'{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"flash":{"message":["emails has been taken, choose another one!"]}}' },
generate: [Function] },
sessionID: 'ffSa89VCV0Mj6uKLrEPMAdNMGLR2I5ML',
session:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true } },
_passport:
在重定向到 /api/signupFail 后,它以某种方式打开了一个新会话。谁能帮我解决这个问题?
这是我的中间件设置:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var logger = require('morgan');
var passport = require('passport');
require('./config/passport')(passport);
var cors = require('cors');
var session = require('express-session');
var flash = require('connect-flash');
var app = express();
var corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
app.use(cors(corsOptions));
app.use(logger('dev'));
app.use(cookieParser('Thespywhodumpedme'));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
var goalsRoute = require('./routes/goalsRoute');
var userRoute = require('./routes/userRoute');
// required for passport
app.use(flash());
app.use(session({ secret: 'keyboard cat',resave: true, saveUninitialized:true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
// use connect-flash for flash messages stored in session
app.use(express.static(path.join(__dirname, 'public')));
app.post('/api/signup', passport.authenticate('local-signup', {
successRedirect: '/api/user/suctest',
failureRedirect: '/api/signupFail',
failureFlash: true
}));
app.get('/api/signupFail', (req, res, next) => {
console.log(req.flash('message')); //this is an empty array
res.status(403).send('fail');
})
这是我的策略设置:
module.exports = function(passport) {
passport.serializeUser((user, done) => {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser((id, done) => {
db.User.getUserById(id, (err, result) => {
done(err, result[0]);
});
});
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
if(!email || !password ) { return done(null, false, req.flash('message','All fields are required.')); }
var salt = '7fa73b47df808d36c5fe328546ddef8b9011b2c6';
db.User.getUserByEmail(email, function(err, rows){
if (err) {
return done(req.flash('message',err));
}
if(rows.length > 0){
return done(null, false, req.flash('message',"emails has been taken, choose another!"));
}
salt = salt+''+password;
var encPassword = crypto.createHash('sha1').update(salt).digest('hex');
var newUser = {
name: req.body.name,
email: email,
password: encPassword,
sign_up_time: new Date()
}
db.User.addOneUser(newUser, (err, result) => {
db.User.getUserByEmail(email, (err, result) => {
return done(err, result[0]);
})
});
});
}));
};
更新 一开始以为跟flash有关,后来打印出session后,发现重定向后又创建了一个新的session。我认为这与后端设置有关。无意中,我从邮递员发送请求时发现这个问题不存在。那时我发现它可能与 Angular 有关,它正在侦听端口 4200,同时在端口 3000 上进行快速侦听。我通过在 httpClient 中硬编码端口号将请求发送到端口 3000。在我设置了将所有 API 调用重定向到端口 3000 的代理之后。一切正常。
解决方案
OK,原来和后端无关。当我通过邮递员发送请求时,一切正常。问题出在前端,我使用的是 Angular 6,Angular 正在侦听端口 4200,同时在端口 3000 上进行快速侦听。我在 Angular 中设置了一个代理,将所有 API 调用重定向到 localhost:3000 并且会话是持久的。