Argon2密码验证通过后,为什么后续请求还是需要重新验证用户身份?
我在用Express和argon2做密码登录功能,登录时argon2.verify对比密码成功后,用session记录了用户ID。但之后调用保护的API时,express-session突然显示用户未登录了,难道每次请求都要重新用argon2验证密码吗?
尝试过这样写登录逻辑:
await argon2.verify(hash, password).then(() => {
req.session.userId = user.id;
res.json({ success: true });
});
但访问/api/dashboard时还是会触发未认证的拦截,明明设置了resave和saveUninitialized为true…
具体来说,Express的session机制是这样的流程:
1. 登录成功后设置req.session.userId
2. Express-session会自动在响应头里设置Set-Cookie
3. 浏览器后续请求需要带上这个cookie
4. 服务端通过cookie中的sessionId还原session对象
常见的问题点有这几个:
第一,检查session中间件配置。很多人会漏掉proxy信任设置(如果你用了nginx之类的反向代理):
第二,检查客户端是否保存了cookie。用浏览器开发者工具看Network选项卡,登录请求的响应头里应该有Set-Cookie,后续请求的请求头里应该有Cookie。如果没带cookie,session自然就丢失了。
第三,跨域问题。如果前端是不同端口或域名,需要这样配置:
第四,axios这类HTTP客户端默认不发送cookie,需要特别设置:
至于argon2验证,你现在的做法是对的 - 只需要在登录时验证一次,成功后把用户ID存入session即可。后续请求通过session.userId判断登录状态,完全不需要重复验证密码。
如果还是不行,可以试着在路由里打印req.session看看是不是真的存进去了:
最近我刚踩过这个坑,花了3个小时才发现是nginx配置漏了proxy_set_header...(捂脸)
你遇到的情况可能是session没正确保存或者丢失了。先检查这几个地方:
1. 确保用了
cookie-parser中间件,因为express-session依赖它。2. session存储设置里
resave和saveUninitialized确实是true,但更重要的是secret是否设置了,比如:secret: 'your-secret-key'。3. 如果用的是浏览器客户端,确认cookies有没有正确发送到服务器端,有时候跨域会干扰cookies。
下面是一个完整的登录和路由保护示例,你可以对比一下:
如果还是有问题,可能是其他地方干扰了session机制,比如CORS配置或者客户端代码没正确处理cookies。多看看控制台的日志输出吧,一般都能找到线索。