我正在尝试在 node.js/express FW 中建立一个包含用户数据的 session 。 我正在使用快速 session 。我还没有使用 session 存储。 我在客户端( Angular )中有 2 个页面,在登录和仪表板之间进行迭代。这个想法是在成功登录后创建 session ,然后路由到仪表板页面。在仪表板页面中,我有一个 anchor ,其中包含指向登录的例程链接:
<a [routerLink]="['/login']" >BackToLogin</a>
当导航回登录页面时(激活路由时),我执行一个带有到 Express 服务器端点的服务,该服务检查请求是否有一个包含请求的 session (我希望是这样)。 问题是我看到 session 不是同一个 session (id 更改)
查看我的代码: 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:负责验证用户并将用户数据存储在 session 中:
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;
这是服务器上负责获取 session 的端点 - session.js - 这就是问题出现的地方 - res.session 的 session ID 与我在之后创建的 session 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;
客户端:
//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']);
}
});
}
我在 github 上发现了类似的问题 - 还没有解决方案: https://github.com/expressjs/session/issues/515 但这可能是 cookie <-> 服务器配置问题。
最佳答案
发现问题了——根本原因是客户端在发出httprequest时没有发送cookie。 为了解决这个问题需要做两件事:
<强>1。 CORS定义
将 CORS 定义设置为 credentials: true 以及 origin(客户端的主机名,可能具有不同的端口\主机名):
app.use(cors({
origin: config.origin,
credentials: true
}));
<强>2。设置凭据
对于每个 http 休息方法(在我的例子中是 get 和 post)添加值为 true 的 withCredentials 属性:
return this.http.get<any>(<path>, { withCredentials: true })
或
return this.http.post<any>(<path>, <body>, { withCredentials:true })
关于node.js - 请求 session 不持久 - Express-Session,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56327572/