javascript 无法访问 Express/NodeJS 中的 req.session 变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21212828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 20:23:57  来源:igfitidea点击:

Cannot access req.session variables in Express/NodeJS

javascriptnode.jssessionexpress

提问by Andrew De Forest

I've seen many variations of this question, but none seemed to solve my issue. I'm trying to set up a Node.jsserver using Express. Here is my server configuration:

我见过这个问题的许多变体,但似乎没有一个能解决我的问题。我正在尝试Node.js使用Express. 这是我的服务器配置:

var express = require('express'),
    RedisStore = require('connect-redis')(express);

var app = express();

app.use(express.urlencoded());
app.use(express.json());
app.use(express.cookieParser());
app.use(express.session({
    store: new RedisStore(), 
    secret: APP_SECRET
}));

// Initialize redis connection
var client = redis.createClient();
client.on('connect', function() {
    console.log('Connected to Redis server')
})
client.on('error', function (err) {
    console.log('Error ' + err);
});

// Enable cross-origin resource sharing
app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With');
  next();
 });

var api = require('./controllers/api.js');

app.post('/login', api.login);
app.get('/auth', api.auth);

app.listen(3000);

And here are some simple routes:

这里有一些简单的路线:

exports.login = function(req, res) {
    var user = new User(req.username, req.password);
    req.session.user = user;
    console.log(req.session.user); //works
    res.json({user:user});
}

exports.auth = function(req, res) {
    console.log(req.session.user); //doesn't work
    res.json(req.session.user);
}

So in my loginroute, I can print the session variable as expected. But if I visit the authroute after visiting the loginroute, the session variable is undefined. How can I get Express sessions to work?

所以在我的login路线中,我可以按预期打印会话变量。但是如果我在访问auth路由后访问login路由,会话变量是未定义的。如何让 Express 会话正常工作?

采纳答案by Fizer Khan

In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.

在典型的 Web 应用程序中,用于对用户进行身份验证的凭据只会在登录请求期间传输。如果身份验证成功,将通过用户浏览器中设置的 cookie 建立和维护会话。

Each subsequent request will not contain credentials or all user data, but rather the unique cookie that identifies the session. In order to support login sessions, You have to serialize and deserialize user instances to and from the session in every request.

每个后续请求将不包含凭据或所有用户数据,而是包含标识会话的唯一 cookie。为了支持登录会话,您必须在每个请求中对会话中的用户实例进行序列化和反序列化。

In your case, you have assigned req.session.user = user;only in /loginrequest. It will not be available for further requests(/auth).

在您的情况下,您req.session.user = user;仅在/login请求中分配。它将无法用于进一步的请求(/auth)。

You have to get user information in /authrequest too by session id. (Or) Better you can use passportfor authentication.

您还必须/auth通过会话 ID获取请求中的用户信息。(或)更好的是您可以使用护照进行身份验证。

回答by Garibaldy Cramer

I think maybe your redis client is not connecting well, try something like this and be sure to start the redis service

我想可能你的redis客户端连接不好,试试这样的方法,一定要启动redis服务

sudo service redis-server start

or the way you are calling The RedisStore variable look at the example

或者你调用 RedisStore 变量的方式看例子

example:

例子:

var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);

app.set('port',process.env.PORT || 3000);

app.use(cookieParser());
app.use(session({
    resave: true,
    saveUninitialized: true,
    store: new RedisStore({
      host: 'localhost',
      port: 6379
    }),
    secret: 'some string/hash secret'
}));


var counter=0;
app.get('/', function(request, response){
  //adding some value to request.session

   counter = counter+1;

  request.session.color = {'anyValue': counter};
  //
  console.log('Session ID: ', request.sessionID);
  console.log('Session: ', request.session);
  response.send('some text counter: '+request.session.color['anyValue']);

});


app.listen(app.get('port'));

回答by Cody Gustafson

The currently accepted answer didn't realize that express.session already handles cookie based sessions with the req.session object. I tried a trimmed down version of yours not using redis and it worked. Looking at the connect-redis docs it looks like you need to pass a session to connect-redis. You are currently passing it express. I believe changing that will fix your problem.

当前接受的答案没有意识到 express.session 已经使用 req.session 对象处理基于 cookie 的会话。我尝试了一个不使用 redis 的精简版,它奏效了。查看connect-redis 文档,您似乎需要将会话传递给connect-redis。您目前正在通过它快递。我相信改变它会解决你的问题。

P.S. I would update your node/express versions as current versions of express no longer have the built in middleware along with other improvements.

PS 我会更新你的 node/express 版本,因为当前版本的 express 不再有内置的中间件以及其他改进。

Newer versions of express:

较新版本的快递:

var session = require('express-session');
var cookieParser = require('cookie-parser');
var json = require('express-json');
var bodyParser = require('body-parser')

Rather than:

而不是:

express.session
express.cookieParser
express.json
express.bodyParser