在Nuxt+Vue SSR应用中如何豁免特定路由/页面的登录授权校验
实现方案说明
首先明确:Nuxt Auth模块可以完成开放特定免登录路由的基础配置,但限制免登录用户跳转其他页面的逻辑需要额外补充,无法仅靠Auth模块默认配置实现全需求
第一步:配置免登录路由白名单(Nuxt Auth模块可直接完成)
无论你使用的是Nuxt2的@nuxtjs/auth-next还是Nuxt3的sidebase/nuxt-auth模块,都支持配置全局路由守卫的白名单:
- Nuxt2 + @nuxtjs/auth-next 配置方式:
在nuxt.config.js中开启全局登录校验:
在需要开放的页面组件中单独关闭登录校验:// nuxt.config.js auth: { redirect: { login: '/login', logout: '/', home: '/dashboard' }, enableGlobalAuthMiddleware: true // 开启全局校验,默认所有路由都需要登录 }, router: { middleware: ['auth'] }<!-- /pages/public/share.vue 示例开放页面 --> <script> export default { auth: false, // 标记该页面不需要登录 // 其他业务逻辑 } </script> - Nuxt3 + sidebase/nuxt-auth 配置方式:
开启全局守卫后,在开放页面的definePageMeta中配置即可:// /pages/public/[shareId].vue 示例开放页面 definePageMeta({ auth: false })
第二步:实现免登录用户的跳转限制(需额外补充逻辑)
这部分需要新增全局路由守卫完成,核心逻辑是判断当前用户是否未登录,且目标路由不在免登录白名单内,直接拦截请求:
- 先定义统一的免登录路由白名单,比如存到
utils/constants.js:export const PUBLIC_ROUTES = ['/public/share', '/public/preview'] - 新增全局路由中间件(优先级高于Auth中间件):
- Nuxt2 实现:新增
middleware/routeGuard.js
然后在import { PUBLIC_ROUTES } from '~/utils/constants' export default function ({ app, route, redirect }) { const isLoggedIn = app.$auth.loggedIn const isToPublicRoute = PUBLIC_ROUTES.some(publicPath => route.path.startsWith(publicPath)) // 未登录且访问非开放路由,直接拦截 if (!isLoggedIn && !isToPublicRoute) { return redirect('/403') // 也可跳转到登录页 } }nuxt.config.js中注册全局中间件:router: { middleware: ['routeGuard', 'auth'] } - Nuxt3 实现:新增
middleware/routeGuard.global.tsimport { PUBLIC_ROUTES } from '~/utils/constants' export default defineNuxtRouteMiddleware((to, from) => { const { status } = useAuth() const isLoggedIn = status.value === 'authenticated' const isToPublicRoute = PUBLIC_ROUTES.some(publicPath => to.path.startsWith(publicPath)) if (!isLoggedIn && !isToPublicRoute) { return navigateTo('/403') } })
- Nuxt2 实现:新增
以上中间件逻辑在SSR场景下会在服务端渲染前执行,不会出现客户端闪跳的问题,完全适配SSR场景。
可选优化方案
如果你的开放页面和内部系统耦合度极低,还可以采用更安全的隔离方案:
- 把开放页面做成独立的静态路由,单独打包部署,和内部系统完全隔离,避免逻辑互相影响
- 开放页面依赖的后端接口单独做签名校验,不依赖用户登录态,进一步提升安全性
内容的提问来源于stack exchange,提问作者Luckytechy
相关产品推荐
相关产品推荐

