You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:18:01