首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >学习 Vue 3 全家桶 - 权限设计

学习 Vue 3 全家桶 - 权限设计

作者头像
Cellinlab
发布2023-05-17 16:57:38
发布2023-05-17 16:57:38
4680
举报
文章被收录于专栏:Cellinlab's BlogCellinlab's Blog

# 登录权限

src/router/index.js 中添加路由:

代码语言:javascript
复制
import Login from '../pages/login.vue';

const routes = [
  // ...
  {
    path: '/login',
    name: 'Login',
    component: Login,
    hidden: true,
  },
];

登录页面 src/pages/Login.vue 中添加登录逻辑:

代码语言:javascript
复制
function handleLogin () {
  formRef.value.validate(async valid => {
    if (!valid) {
      console.log('invalid');
      return false;
    }
    loading.value = true;
    const { code, message } = await useStore.login(loginForm);
    loading.value = false;
    if (code === 0) {
      router.replace(toPath || '/');
    } else {
      message.error(message);
    }
  })
}

mock 登录接口:

代码语言:javascript
复制
const mockAPI = {
  login: {
    url: '/user/login',
    type: 'POST',
    response: config => {
      const { username, password } = config.body;
      const token = `token-${username}`;

      if (password !== `${username}123`) {
        return {
          code: 200,
          message: 'Account or password is incorrect',
        };
      }
      return {
        code: 200,
        data: {
          token,
        }
      };
    }
  }
};

登录成功后,需要把这个 token 存储在本地存储里面,留着后续发送数据。实现比较简单,直接把 token 存储到 localStorage 中就行。

拿到 token 后,为了进行接口权限认证,要把 token 放在 HTTP 请求的 header 内部。

代码语言:javascript
复制
service.interceptors.request.use(
  (config) => {
    if (store.getters.token) {
      config.headers['X-Token'] = getToken();
    }
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  },
);

上面只是解决了网络请求的拦截,还可以使用 Vue-Router 的 导航守卫实现对页面的拦截。

代码语言:javascript
复制
router.beforeEach(async (to, from, next) => {
  const token = getToken();
  if (to.path !== '/login') {
    if (token) {
      next();
    } else {
      next('/login');
    }
  } else {
    next();
  }
});

之前开发项目的时候,和登录注册相关的配置,不需要自己管理 token,都是后端直接设置 cookie。

但是,在现在这种前后端分离的场景下,通常前后端项目都会部署在不同的机器和服务器之上,Cookie 在跨域上有诸多的限制。所以在这种场景下,更适合手动地去管理权限,于是就诞生了现在流行的基于 token 的权限解决方案,也可以把 token 理解为手动管理的 cookie。

# 角色权限

在管理系统开发中,订单页面是所有人都可以看到的,但是像账单的查询页面,以及其他一些权限更高的页面,需要管理员权限才能看到。这时候,就需要对系统内部的权限进行分级,每个级别都对应着可以访问的不同页面。

通常使用的权限解决方案就是 RBAC 权限管理机制。简单来说,就是在下图所示的这个模型里,除了用户和页面之外,需要一个新的概念,就是角色。每个用户有不同的角色,每个角色对应不同的页面权限,这个数据结构的关系设计主要是由后端来实现。

在用户登录完成之后会获取页面的权限数据,也就是说后端会返回当前页面的动态权限部分。

这样有一部分页面路由是写在代码的 src/router/index.js 中,另外一部分页面路由通过 axios 获取数据后,通过调用 vue-router 的 addRoute 方法动态添加进项目整体的路由配置中。

可以在 Vuex 中注册 addRoute 这个 action,通过后端返回的权限页面数据,调用 router.addRoute 新增路由。

代码语言:javascript
复制
addRoutes({ commit }, accessRoutes) {
  const removeRoutes = [];
  accessRoutes.forEach((route) => {
    const removeRoute = router.addRoute(route);
    removeRoutes.push(removeRoute);
  });
  commit('SET_ROUTES', accessRoutes);
}

与新增路由对应,在页面重新设置权限的时候,需要用 router.removeRoute 来删除注册的路由,这也是上面的代码中还有一个 removeRoutes 来管理动态路由的原因。

需要把动态路由的状态存储在本地存储里,否则刷新页面之后,动态的路由部分就会被清空,页面就会显示 404 报错。

需要在 localStorage 中把静态路由和动态路由分开对待,在页面刷新的时候,通过 src/router/index.js 入口文件中的 routes 配置,从 localStorage 中获取完整的路由信息,并且新增到 vue-router 中,才能加载完整的路由。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/2/11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 登录权限
  • # 角色权限
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档