Node+Express.js 认证后无需在请求中传递即可获取用户名的实现方法
实现方案
核心思路
你完全可以通过JWT实现用户名的自动传递,不用依赖前端传参,也不会出现多用户覆盖的问题:登录时你已经把用户名写入了JWT的payload,后续请求只要带上这个JWT,我们通过全局身份校验中间件解析JWT,把用户名挂载到每个请求独立的req对象上,所有路由都可以直接读取。
具体操作步骤
1. 编写JWT校验中间件
新建middleware/auth.js文件,写通用校验逻辑:
const jwt = require('jsonwebtoken') // 需和生成JWT时使用的secret保持一致 const secret = '你的JWT加密密钥' module.exports = (req, res, next) => { // 优先从httpOnly cookie中取token,也兼容前端放在请求头的场景 const token = req.cookies.token || req.headers.authorization?.split(' ')[1] if (!token) { return res.status(401).send({msg: '未登录'}) } try { // 解析JWT拿到存入的用户名信息 const decoded = jwt.verify(token, secret) // 将用户信息挂载到req对象,每个请求的req是独立实例,不会出现多用户覆盖 req.user = decoded // 放行到后续路由逻辑 next() } catch (err) { return res.status(401).send({msg: '登录状态无效'}) } }
2. 给需要身份校验的路由添加中间件
在路由注册入口,给需要登录权限的接口挂载中间件,示例:
const authMiddleware = require('./middleware/auth') // 登录接口不需要加校验,其他需要权限的接口都添加 app.use('/note', authMiddleware, require('./routes/load')) // 其他需要权限的路由按相同规则添加即可
3. 修改load.js业务逻辑
不需要再从请求参数中取用户名,直接从req对象读取即可:
router.post("/note/load", async (req, res) => { try { // 直接取中间件挂载的用户名,无需依赖前端传参 const username = req.user.username // 注意不要把对象转字符串当集合名,直接用用户名字符串即可 const usercollection = userdb.collection(username) const loadNote = await usercollection.find().toArray() res.status(200).send(loadNote) } catch (err) { res.status(500).send({msg: '加载失败'}) } })
现有代码优化建议
你当前的登录逻辑存在冗余和不规范问题,可以同步调整:
- 刚生成的token不需要立即校验合法性,这段冗余代码可以直接删除
- 不要混用
await和回调函数写法,统一用async/await逻辑更清晰,也更容易排查错误 - 状态码可以统一规范:用户不存在返回404、密码错误返回400、权限不足返回401,避免状态码重复导致前端无法区分错误类型
内容的提问来源于stack exchange,提问作者tontsa28
相关产品推荐
相关产品推荐

