未在浏览器中设置Express会话cookie

时间:2019-03-12 12:00:52

标签: node.js express passport.js amazon-elb

我在尝试通过代理(最初为NGINX,现在为AWS ALB)来实现HTTPS以保护与节点服务器的连接时遇到问题。我的login请求正在处理中,但是login之后的后续请求被标记为isAuthenticated === false,因此我的节点应用返回了401。

我知道isAuthenticated === false是由未在浏览器中设置会话cookie引起的,但是我似乎无法弄清楚为什么未设置(或发送?)会话cookie。

我正在如下配置快速会话:

app.use(cookieParser('secret'));

app.set('trust proxy', 1);

// add & configure middleware
app.use(session({
    name: 'session',
    store: new redisStore(),
    secret: 'secret',
    resave: false,
    saveUninitialized: false,
    cookie: { httpOnly: true,
        secure: true }
}));

我的节点应用程序位于一个AWS Application Load Balancer后面,该应用程序通过HTTP与该应用程序通信,因此我已将trust proxy配置为1。

我的护照配置和本地策略就在下面:

// configure passport.js to use the local strategy
passport.use(new LocalStrategy(
    { usernameField: 'email' }, 
    (email, password, done) => {
        mysql.getConnection((err, conn) => {
            conn.query('SELECT u.user_id, u.email, u.password, o.uuid FROM user AS u INNER JOIN organization AS o ON o.id = u.org_id WHERE email = ?;', [email], ( err, rows ) => {
                if (err) throw err;

                if (rows.length !== 1)
                    return done(null, false, { message: 'User does not exist.\n' });
                else if (!bcrypt.compareSync(password, rows[0].password))
                    return done(null, false, { message: 'Incorrect password.\n' });
                else{
                    return done(null, {user_id: rows[0].user_id, email: email, uuid: rows[0].uuid});
                }
            });
            conn.release();
        });
    }
));

react客户端发出的请求是:

axios.post('https://sub.mydomain.com' + '/api/login', userObj, {withCredentials: true})
.then(res => {
    if (res.status === 200) {
        initUser(res.data, true);
    }
    else {
        this.setState({errors: {password: 'Incorrect username or password'}})

        this.props.history.push('/login');
    }
})
.catch((e) => {
    this.setState({errors: {password: 'Unable to login'}})

    this.props.history.push('/login');
});

发出请求时,如我所料,我将返回200状态以及用户信息。请参阅以下PostMan的屏幕截图: enter image description here

这些也是Chrome中的响应标头:

access-control-allow-credentials: true
access-control-allow-origin: https://sub.mydomain.com
content-length: 89
content-type: text/html; charset=utf-8
date: Tue, 12 Mar 2019 07:49:45 GMT
etag: W/"59-T0xi+VpB6A/MLCHMb8Qz3Pq9dwc"
status: 200
vary: Origin
x-powered-by: Express

似乎在某些地方,会话cookie要么无法从节点应用发送,要么无法在浏览器中设置。

我在本地计算机上运行完全相同的代码,并且在浏览器中设置了cookie没问题。我的本地服务器和服务器之间的唯一区别是节点应用程序前面的ALB,并且我在本地服务器上设置了secure: false(因为我没有使用HTTPS)。

仅供参考-我最初尝试在服务器上使用NGINX proxy_pass来处理HTTPS连接,并且遇到了同样的问题。在找不到NGINX解决方案后,我曾尝试删除代理通行证并使用AWS Application Load Balancer(我认为NGINX配置可能存在问题)。这使我相信问题在于快速会话配置是这里的共同点,但是我可能会遗漏其他东西。

FYI 2-我尝试将trust proxy设置为true123等,也尝试设置{{1} }到secure,还尝试将false设置为httpOnly-以及上述内容的无数种形式,但我似乎仍未在浏览器中获得cookie。

FYI 3-我尝试删除代理并恢复到与Node应用程序的直接HTTP连接,但仍然没有在浏览器(或PostMan)中获取cookie。

希望在这里的人可以指出我想解决的一些东西。

谢谢!

1 个答案:

答案 0 :(得分:0)

因此,经过数天的调查,结果是我的Redis服务器已终止并且无法重新启动。 facepalm

由于未连接到Redis存储以将会话信息保存在服务器端,因此未生成(或存储)sessionID。

启动Redis服务器可以立即解决此问题,但是,如果express / passport有一些详细的日志记录来通知用户,那就太好了。

希望其他人觉得这有用!