简体   繁体   English

请求会话不持久 - 快速会话

[英]request session not persistent - express-session

I'm trying to have a session containing user data in the node.js/express FW.我正在尝试在 node.js/express FW 中创建一个包含用户数据的会话。 I'm using express-session.我正在使用快速会话。 I'm not using session store yet.我还没有使用会话存储。 I have 2 pages in the client (angular) where I iterate between - Login and Dashboard.我在客户端(角度)中有 2 个页面,我在其中进行迭代 - 登录和仪表板。 The idea is to create the session after successful login, then routing to the dashboard page.这个想法是在成功登录后创建会话,然后路由到仪表板页面。 In the dashboard page I have an anchor with routinlink to the login:在仪表板页面中,我有一个带有 routinlink 登录的锚点:

<a [routerLink]="['/login']" >BackToLogin</a>  

When navigating back to the loginPage (when activating a route), I execute a service with an end-point to the express server which check if the request has a session with a request in it (I expect it to be).当导航回 loginPage 时(激活路由时),我执行一个服务,它的端点指向 express 服务器,该服务器检查请求是否有一个包含请求的会话(我希望它是)。 The problem is that I see that the session is not the same session (the id changes)问题是我看到会话不是同一个会话(id改变)

See my code: Node.js side - server.js file:查看我的代码:Node.js 端 - server.js 文件:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');

const session = require ('express-session'); 
var cookieParser = require('cookie-parser');
const SESS_NAME = 'sid'; 

app.use(session({
    name:SESS_NAME,
    key: 'user_sid',
    resave:false, 
    saveUninitialized:false, 
    secure: process.env.NODE_ENV ==="production",  
    secret:'<some random text>', 
    cookie:{

            httpOnly: true, 
            secure: process.env.NODE_ENV ==="production", 
            expires: 60000 
           }
}));

app.use(bodyParser.text());
app.use(bodyParser); 
app.use(bodyParser.urlencoded({ 
    extended: true
}));

app.use(cors()); //No limitation for test reasons

app.use(cookieParser());

//disabled on purpose
//var sessionManagement = require('./middleware/sessionManagement'); 
// API   
app.use("/", require("./api/v1/routes.js"))//This file includes:
/*
const express = require('express');
const router = express.Router();
router.use("/login", require('./login'));
router.use("/session", require('./session'));
module.exports = router;
*/
...etc
app.listen(config.port, () => console.log(`Process ${process.pid}: Listening on port ${config.port}`));

login.js on the server: responsible for validating user and store user data in session:服务器上的 login.js:负责验证用户并在会话中存储用户数据:

const express = require('express');
const router = express.Router();
const schema = require('./objectSchemaJson.schema.json');
const scehmaCheck = require('../../middleware/checkForSchema')(schema);//this is 
a schema check (middleware) - if suceeded continue (next)

const storeSession = (req, dataResult) =>
{
    if (<dataResult return with valid use data>) //This is "where the magic happanes"
    {
        req.session.user = { 
            username: <get userName from dataResult>, 
            ID: <Get ID from dataResult>, 
            Role: <Get Role from dataResult> 
        }    
    }
}
router.use("/", scehmaCheck, (req, res, next) => {
    return GetUserDataFROmDB(req.body).then((dataResult) => { //reaching the DB - not mentioned here on purpose
        storeSession(req, dataResult); // This is where the session set with user data
        res.status(200).json(dataResult);
    }).catch((err) => {
        next({
            details: err
        })
    });
});

module.exports = router;

This is the end point on the server that responsible for getting the session - session.js - This is where the problem appears - the res.session has a session ID which is different that the one I created after the login这是负责获取会话的服务器上的端点 - session.js -这就是问题出现的地方 - res.session 的会话 ID 与我在登录后创建的会话 ID 不同

const express = require('express');
const router = express.Router();

 hasSession : function(req, res) //This is where the problem appears - the res.session has a session ID which is different that the one I created after the login
{
    if (req.session.user)
    {
        res.status(200).json(
            {
                recordsets: [{Roles: req.session.Roles, UserName: req.session.user.username}]
            });
    }
    else{
        res.status(200).json({});
    }
}

router.use("/", (req, res, next) => { return sessionManagement.hasSession(req, res, next)});

module.exports = router;

Client side:客户端:

//HTML:
<div>
  <label>Username:</label>
  <input type="text" name="username" [(ngModel)]="userName" />
</div>
<div>
  <label>Password:</label>
  <input type="password" name="password" [(ngModel)]="password"/>
</div>
<div>
  <button (click)="login()">Login</button>
</div>

//COMPONENT:

login()
  {
    this.srv.login(this.userName, this.password).subscribe(result => 
      {
        if (<result is valid>)
        {
          this.router.navigate(['/dashboard']);
        } 

      }
    );
  }

//This reach the node.js endpoint and routing to the session.js end point - it is executes when the router-outlet activated in the app.component:
/*
    onActivate(componentRef : any)
      {
        if (componentRef instanceof LoginComponent)
        {
          componentRef.getSession();
        }
      }
*/



getSession() : void
  {
    this.sessionService.getSession().subscribe( result => 
      {
        if (<result is valid>)
        {
          this.router.navigate(['/dashboard']);
        }
      });
  } 

I found a similar question on github - no solution yet: https://github.com/expressjs/session/issues/515 but it might be a cookie <-> server configuration issue.我在 github 上发现了一个类似的问题 - 还没有解决方案: https : //github.com/expressjs/session/issues/515但它可能是一个 cookie <-> 服务器配置问题。

Found the problem - the root cause was that the client didn't send a cookie when making an httprequest.找到问题了-根本原因是客户端在发出http请求时没有发送cookie。 2 things needed to be done in order to solve the problem:为了解决这个问题,需要做2件事:

1. CORS Definition 1. CORS 定义

Set the CORS definition to creadentials: true along with the origin (the host name of the client, which is probably with a different port\\hostname):将 CORS 定义设置为 credentials: true 以及源(客户端的主机名,可能具有不同的端口\\主机名):

app.use(cors({ 
    origin: config.origin,
    credentials: true
}));

2. Set crendentials 2. 设置凭据

For every http rest method (get and post, in my case) add withCredentials property with a value of true:对于每个 http rest 方法(在我的情况下为 get 和 post)添加值为 true 的 withCredentials 属性:

return this.http.get<any>(<path>, { withCredentials: true })

or或者

return this.http.post<any>(<path>, <body>, { withCredentials:true })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM