首页 > 解决方案 > 角度与快递,会话不是持久的。每个请求都会创建一个新会话

问题描述

原始问题

我正在使用 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 的代理之后。一切正常。

标签: node.jsangularexpresspassport.js

解决方案


OK,原来和后端无关。当我通过邮递员发送请求时,一切正常。问题出在前端,我使用的是 Angular 6,Angular 正在侦听端口 4200,同时在端口 3000 上进行快速侦听。我在 Angular 中设置了一个代理,将所有 API 调用重定向到 localhost:3000 并且会话是持久的。


推荐阅读