使用Express开发带API的应用时JWT无效如何重定向到登录页
解决方案
第一步:先优化后端响应状态码(必改)
你当前的token校验中间件无论成功失败都返回200状态码,前端无法全局统一识别无效token的场景,先修改checkToken.js:
const jwt = require('jsonwebtoken') const checkToken = (req, res, next) => { const ah = req.headers.authorization const token = ah && ah.split(' ')[1] if (!token) return res.status(401).json({ msg: "No token offered."}) jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { if (err) return res.status(401).json({ msg: "Invalid token offered."}) req.user = user next() }) } module.exports = checkToken
所有token无效、缺失的场景统一返回401状态码,方便前端全局捕获。
第二步:配置Axios全局拦截器(无需每个ejs单独写校验)
这是对应的最佳实践:全局配置Axios的请求/响应拦截器,不用在每个页面单独写校验逻辑。
把以下代码放到你所有页面都会引入的公共JS文件中(比如放在公共头部引入的common.js里,所有ejs都加载这个文件即可):
// 全局请求拦截器:自动给所有请求加Authorization头,不用每个接口单独写 axios.interceptors.request.use(config => { const token = localStorage.access_token if (token) { config.headers.Authorization = `Bearer ${token}` } return config }, error => Promise.reject(error)) // 全局响应拦截器:统一捕获401错误,自动跳登录 axios.interceptors.response.use(response => response, error => { // 捕获401错误 if (error.response && error.response.status === 401) { // 先清掉无效的本地token localStorage.removeItem('access_token') // 排除登录、注册页,避免循环重定向 const publicPages = ['/auth/login', '/auth/register'] const currentPath = window.location.pathname if (!publicPages.includes(currentPath)) { window.location.href = '/auth/login' } } return Promise.reject(error) })
配置完之后,你原来的接口请求代码可以简化,不用每个接口都传headers:
// 简化后的getTodos代码 const getTodos = async () => { let response = await axios.get('/api/todos/all', { headers: { 'Content-Type': 'application/json' } }) // 原有逻辑不变 }
第三步:无业务请求的页面补充处理
如果存在部分页面不需要调用任何业务API,也需要做token校验的话,只需要在公共JS里加一段全局初始化逻辑即可,不需要每个页面单独写:
// 全局初始化逻辑,所有页面加载时执行 ;(async () => { const publicPages = ['/auth/login', '/auth/register'] const currentPath = window.location.pathname const token = localStorage.access_token // 非公开页且本地有token时,调用轻量校验接口确认有效性 if (!publicPages.includes(currentPath) && token) { try { // 可以在后端加一个极简的token校验接口,不需要返回业务数据 await axios.get('/api/auth/check-token') } catch (e) { // 校验失败会被上面的响应拦截器自动处理跳登录 } } })()
额外优化(可选)
如果想进一步避免未登录用户访问受保护页面时的闪烁问题,可以给服务端的前端路由加基础判断:如果是访问非公开页且jwt存储在cookie里的话,服务端可以直接读取cookie校验,无效就直接302跳登录,体验更好。
内容的提问来源于stack exchange,提问作者VHK
相关产品推荐
相关产品推荐

