当前位置:首页 > 技术 > 正文内容

基于 Vue 和 Vuex 的后台登录与动态权限路由实现

访客 技术 2026年10月23日 2

在构建中后台管理系统时,权限控制和安全性是系统的核心基石。一个成熟的方案通常需要实现:根据用户权限动态过滤路由表,并同步生成侧边栏菜单。本文将探讨如何通过 Token 机制和 Vue 路由守卫实现这一套完整的鉴权流程。

鉴权流程设计思路

整个鉴权过程可以分为登录鉴权和权限加载两个阶段:

  • 登录鉴权:用户提交凭据后,服务端验证合法性并返回身份标识(Token)。前端将 Token 持久化存储在 Cookie 或 LocalStorage 中,以维持会话状态。
  • 身份校验:在路由跳转前,通过 Token 请求用户信息接口(获取角色 Role、权限列表等)。根据角色计算出该用户拥有的异步路由,并通过 router.addRoute 动态挂载。

为了确保状态的一致性,建议使用 Vuex 或 Pinia 全局状态管理来维护用户信息和路由表。

登录逻辑的实现

当用户触发登录操作时,前端通过 Action 提交登录请求。成功获取 Token 后,将其存入状态管理库和浏览器持久化缓存中。

// 视图层调用登录接口
async function handleUserAuth() {
  try {
    await this.$store.dispatch('account/authenticate', this.loginData);
    // 登录成功后跳转至重定向页面或首页
    this.$router.push({ path: this.redirect || '/' });
  } catch (error) {
    this.$message.error('身份验证失败,请检查账号密码');
  }
}

// Vuex Action 实现
const actions = {
  authenticate({ commit }, credentials) {
    const { account, password } = credentials;
    return new Promise((resolve, reject) => {
      api.login(account.trim(), password)
        .then(response => {
          const { token } = response.data;
          // 将 Token 存入 Cookie,设置有效期
          Cookies.set('Admin-Token', token);
          commit('UPDATE_TOKEN', token);
          resolve();
        })
        .catch(err => reject(err));
    });
  }
};

全局路由守卫与动态权限加载

在页面刷新或切换路由时,利用 router.beforeEach 钩子拦截请求。如果本地存在 Token 但 Vuex 中尚未加载用户信息,则触发信息获取流程。

router.beforeEach(async (to, from, next) => {
  const hasToken = getToken();

  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' });
    } else {
      const hasPermissions = store.getters.userRoles && store.getters.userRoles.length > 0;
      if (hasPermissions) {
        next();
      } else {
        try {
          // 获取当前用户的详细权限信息
          const { roles } = await store.dispatch('account/fetchUserProfile');
          
          // 根据角色生成可访问的路由表
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles);
          
          // 动态注入路由
          accessRoutes.forEach(route => {
            router.addRoute(route);
          });

          // 确保路由挂载完成后再进行跳转
          next({ ...to, replace: true });
        } catch (err) {
          // 异常情况下强制注销并重定向至登录页
          await store.dispatch('account/resetToken');
          next(`/login?redirect=${to.path}`);
        }
      }
    }
  } else {
    // 无 Token 的情况下,判断是否在白名单中
    isWhiteList(to.path) ? next() : next(`/login?redirect=${to.path}`);
  }
});

存储策略的选择

在实际应用中,不建议将完整的用户信息(如权限列表、用户名)直接存储在本地缓存。主要原因如下:

  1. 数据一致性:若用户在其他终端修改了资料,本地缓存的过期数据会导致界面显示异常。
  2. 安全性:权限信息应由服务端实时下发,前端仅负责持久化 Token。

因此,最佳实践是:仅在 Cookie 中保留 Token。每当页面刷新(Vuex 状态重置)时,通过 Token 重新向后端请求最新的 user_info。这种方案在微服务架构下尤为适用,它确保了每一次会话都能获取到最精准的权限视图。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。