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

Nuxt.js中如何限制特定路由仅对持有有效JWT令牌的客户端开放及验证逻辑实现位置问询

刚好在Nuxt里做过不少JWT路由保护的需求,我分Nuxt 2和Nuxt 3两种主流版本来给你讲具体实现,毕竟两者的架构差异挺大的:

在Nuxt 2中实现JWT校验保护路由

Nuxt 2里核心是用**中间件(Middleware)**来拦截路由请求,同时在API路由里单独做令牌校验:

1. 创建路由保护中间件

在项目根目录的 middleware/ 文件夹下新建 auth.js,写入校验逻辑:

import jwt from 'jsonwebtoken'

export default function ({ req, res, redirect }) {
  // 优先从请求头拿令牌(服务端渲染场景),其次从cookie拿(客户端渲染场景)
  const token = req.headers.authorization?.split(' ')[1] || req.cookies.token

  // 无令牌直接跳转到登录页
  if (!token) {
    return redirect('/login')
  }

  try {
    // 替换成你自己的JWT密钥,建议存在环境变量里
    jwt.verify(token, process.env.JWT_SECRET)
  } catch (err) {
    // 令牌过期或无效,清空cookie并跳转登录
    res.clearCookie('token')
    return redirect('/login')
  }
}

2. 应用中间件到受保护路由

  • 单个页面保护:在需要限制的页面组件(比如 pages/dashboard.vue)里添加配置:
<script>
export default {
  middleware: 'auth' // 指定使用刚才创建的auth中间件
}
</script>
  • 全局路由保护:如果大部分路由都需要校验,可在 nuxt.config.js 里全局注册:
export default {
  router: {
    middleware: ['auth']
  }
}

3. API路由的JWT校验

对于后端API(server/api/ 下的路由),直接在路由处理函数开头做校验:

import jwt from 'jsonwebtoken'

export default function (req, res) {
  const token = req.headers.authorization?.split(' ')[1]
  
  if (!token) {
    res.status(401).json({ message: '未提供有效令牌' })
    return
  }

  try {
    const decodedUser = jwt.verify(token, process.env.JWT_SECRET)
    // 可以把解码后的用户信息挂载到req上,供后续逻辑使用
    req.user = decodedUser
    // 处理正常的API请求逻辑
    res.status(200).json({ data: '仅授权用户可见的数据' })
  } catch (err) {
    res.status(401).json({ message: '令牌无效或已过期' })
  }
}
在Nuxt 3中实现JWT校验保护路由

Nuxt 3基于Nitro引擎,支持页面中间件和服务端中间件两种方式,API路由的校验逻辑也更简洁:

1. 页面级路由保护

在 middleware/ 文件夹下新建 auth.ts(或js):

import { jwtVerify } from 'jose' // 推荐用jose库,比jsonwebtoken更适配现代Node环境

export default defineNuxtRouteMiddleware(async (to, from) => {
  // 从cookie或请求头获取令牌
  const token = useCookie('token').value || useRequestHeaders(['authorization']).authorization?.split(' ')[1]

  if (!token) {
    return navigateTo('/login')
  }

  try {
    // 验证令牌有效性
    await jwtVerify(token, new TextEncoder().encode(process.env.JWT_SECRET))
  } catch (err) {
    // 令牌无效,清空cookie并跳转登录
    useCookie('token').value = null
    return navigateTo('/login')
  }
})

然后在需要保护的页面组件里通过 definePageMeta 绑定中间件:

<script setup>
definePageMeta({
  middleware: 'auth'
})
</script>

2. API路由的JWT校验

在 server/api/ 下的路由文件(比如 protected.get.ts)里,直接在处理函数开头做校验:

import { jwtVerify } from 'jose'

export default defineEventHandler(async (event) => {
  const token = getRequestHeader(event, 'authorization')?.split(' ')[1]
  
  if (!token) {
    throw createError({ statusCode: 401, message: '未授权访问' })
  }

  try {
    const { payload } = await jwtVerify(token, new TextEncoder().encode(process.env.JWT_SECRET))
    // 将用户信息挂载到event.context,供后续逻辑使用
    event.context.user = payload
    return { data: '仅授权用户可访问的API数据' }
  } catch (err) {
    throw createError({ statusCode: 401, message: '令牌无效或已过期' })
  }
})

关键提醒

注意:前端中间件只是用来优化用户跳转体验,绝对不能替代后端API的JWT校验! 前端逻辑可以被篡改绕过,只有后端的校验才能真正保证接口的安全性。

内容的提问来源于stack exchange,提问作者user16799703

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:19:08