如何将app.post()登录接口的jwt token或user_id传递到app.get()路由
实现方案分为两类场景,你可以根据你的项目架构选择:
1. 前后端分离场景(前端用Ajax/fetch提交登录请求)
- 登录成功后前端将接口返回的
token/user_id存在localStorage/sessionStorage中 - 前端请求
/路由时,将token放在请求头Authorization中,格式为Bearer <你的token>,也可以将user_id拼在URL参数中 - 服务端
/路由解析对应位置的参数即可,示例代码:
// 需提前引入jsonwebtoken依赖 app.get('/', (req, res) => { // 解析请求头中的token const authHeader = req.headers.authorization let userInfo = null if (authHeader?.startsWith('Bearer ')) { const token = authHeader.split(' ')[1] try { // 校验token合法性,secret要和你签名时的密钥一致 userInfo = jwt.verify(token, 'secret') } catch (err) { // token过期或伪造,清空信息 userInfo = null } } // 将用户信息传给模板渲染 res.render('index', { user_id: userInfo?.id, isLogin: !!userInfo }) })
2. 服务端渲染场景(原生form表单提交登录,无前端Ajax逻辑)
- 首先修改你的登录接口逻辑,登录成功后将token存入cookie,再重定向到
/路由,注意还要修复你原有代码的bug:bcrypt.compare是异步方法,必须加await,否则判断逻辑永远为真:
app.post('/api/login', async (req, res) => { const { emailid, password } = req.body const user = await User.findOne({ emailid }).lean() if (!user) { return res.json({ status: 'error', error: " Invalid username/Password" }) } // 新增await,修复异步判断bug if (await bcrypt.compare(password, user.password)) { const token = jwt.sign({ id: user._id, emailid: user.emailid }, 'secret', { expiresIn: '24h' }) // 将token存入httpOnly cookie,避免XSS攻击,有效期和token一致 res.cookie('auth_token', token, { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 }) // 重定向到首页 return res.redirect('/') } res.json({ status: 'error', error: " Invalid username/Password" }) })
- 然后改造
/路由,解析cookie中的token即可,需要提前安装注册cookie-parser中间件:
// 注册cookie-parser中间件,写在所有路由之前 const cookieParser = require('cookie-parser') app.use(cookieParser()) app.get('/', (req, res) => { const token = req.cookies.auth_token let user_id = null if (token) { try { const decoded = jwt.verify(token, 'secret') user_id = decoded.id } catch (err) { // 无效token直接清空cookie res.clearCookie('auth_token') } } res.render('index', { user_id: user_id }) })
内容的提问来源于stack exchange,提问作者Kaartik Nayak
相关产品推荐
相关产品推荐

