用户权限控制(Token登录)

1.用户权限控制

1.1 用户登录

1.1.1 流程分析

1) 用户登录界面,需要输入手机号密码

2) 登录组件 login.vue

  • 登录按钮

 
type="primary" :loading="loading" @click="submit('login-form')">{{ loading ? 'Loading...' : '登录' }}

  • 提交表的方法

 
 //
提交登录表单
 submit(ref) {
      //
校验
      this.$refs[ref].validate(valid => {
        if (!valid) return false;
 
        this.error = null;
        this.loading = true;
 
        //
发送登录请求
        this.$store.dispatch("createToken", this.model)
          .then(res =
> {
            if (res.state !==
1) {
              this.error = {
                title:
"Error occurred",
                message:
"Abnormal, please try again later!"
              };
            }
            this.$router.replace({ path: this.$route.query.redirect ||
"/" });
            this.loading = false;
          })
          .catch(err =
> {
            this.loading = false;
          });
      });
    }
  }

  • this.$store.dispatch("createToken", this.model)
    • 这段代码的意思是调用 store仓库的actions.js中的createToken方法

  • 发送登录请求,进行登录的代码

 
  /**
   *
创建新的客户端令牌
   */
  createToken: async ({ commit }, { username, password }) =
> {
    //
请求后台登录接口
    const res = await TokenService.userLogin({
      phone: username.trim(),
      password: password.trim()
    });
 
    console.log(res);
 
    //
判断结果不等于1,登录失败
    if (res.state !== 1) {
      return Promise.resolve(res);
    }
 
    //
获取到content
    const result = res.content;
 
    //
token保存
    commit(CHANGE_SESSION, {
      accessToken: result.access_token
    });
     
    return res;
  },

  • TokenService

 
import { TokenService, UserService } from
"../services";

 
//
登录请求 async ES6语法, 作用: 发送异步请求
export const userLogin =  async (data) => {
 //await
表示等待接收返回的数据
 return await PostRequest(`${process.env.VUE_APP_API_FAKE}/user/login${Serialize(data)}`)
}

1.2 动态获取用户菜单

1.2.1 流程分析

1) 在我们登录成功后, 会立即发送第二个请求, 来获取用户的菜单权限列表

2) 在actions.js 中完成请求后台接口 获取数据的操作

 
  /**
   *
获取当前登录用户权限
   */
  getUserPermissions: async ({ commit }) =
> {
    //
1.请求后台 获取当前用户的权限
    const res = await UserService.getUserPermissions();
 
    //
2.判断
    if (!res.success) {
      //
获取失败直接返回 false
      return res.success;
    }
 
    //
3.获取数据成功,取出菜单 与 资源列表
    const { menuList, resourceList } = res.content;
 
    //
4.下面的代码 就是在生成树形结构的菜单
    let menus = [];
    const formatMenu = treeData =
> {
      if (treeData.length
> 0) {
        return treeData.map(item =
> formatMenu(item));
      }
      const result = {};
 
      //shown
等于表示可以显示,将内容保存
      if (treeData.shown == 1) {
        result.id = treeData.id;
        result.text = treeData.name;
        result.label = treeData.name;
        result.name = treeData.href;
        result.icon = treeData.icon;
        result.shown = treeData.shown;
      } else {
        return
"";
      }
 
      //
获取子节点
      if (treeData.subMenuList) {
        result.children = [];
        treeData.subMenuList.forEach(item =
> {
          formatMenu(item) && result.children.push(formatMenu(item));
        });
 
        if (result.children.length ===
0) {
          delete result.children;
        }
      }
      return result;
    };
 
    const memusMap = {};
 
    const splapMenu = treeData =
> {
      if (treeData.length
> 0) {
        return treeData.map(item =
> splapMenu(item));
      }
      const result = {};
      result.id = treeData.id;
      result.text = treeData.name;
      result.label = treeData.name;
      result.name = treeData.href;
      result.icon = treeData.icon;
      result.shown = treeData.shown;
      result.name && (memusMap[result.name] = result);
 
      if (treeData.subMenuList) {
        result.children = [];
        treeData.subMenuList.forEach(item =
> {
          result.children.push(splapMenu(item));
        });
      }
      return result;
    };
 
    splapMenu(menuList);
 
    menus = formatMenu(menuList);
    commit(CHANGE_SIDERBAR_MENU, menus);
    return { menus, resourceList, menuList, memusMap };
  },

1.3 验证Token

1.3.1 导航守卫

在执行路由之前先执行的一些钩子函数,比如验证用户是否有权限之类的操作,就需要使用.

1) authorize.js 中配置了导航守卫,来对用户的登录进行限制

 
  //
导航守卫 to要访问的url, from从哪个路径跳转过来, next() 放行
  router.beforeHooks.unshift((to, from, next) => {
    //
不需要验证直接放行
    if (!to.meta.requireAuth) return next();
 
    //
需要验证token,调用 store中的checkToken方法
    store.dispatch("checkToken").then(valid => {
      //
判断是否存在token
      if (valid) {
        //
发送请求到后台,在后台再次判断token是否存在
        store.dispatch("getUserPermissions").then(res => {
       
          if (!res) {
            //
失效 清除token
            store.dispatch(
"deleteToken");
 
            //
跳转到登录页面
            return next({ name: "ToLogin" });
          }
 
          //token
正确, 导航到对应的页面
          const { memusMap } = res;
          if (memusMap.Courses && to.name ===
"Home") {
            return next();
          } else if (memusMap[to.name]) {
            return next();
          } else if (Object.keys(memusMap).length
> 0) {
            return next({ name: memusMap[Object.keys(memusMap)[
0]].name });
          } else {
            next({ name:
"PermissionDenied" });
          }
        });
        return next();
      }
      // unauthorized
      console.log(
"Unauthorized");
 
      //
用户没有登录 跳转到登录页面
      next({ name: "Login", query: { redirect: to.fullPath } });
    });
  });

 
checkToken: async ({ commit, getters }) =
> {
    //
取出token
    const token = getters.session.accessToken;
 
    if (!token) {
      //
不可用
      return Promise.resolve(false);
    }
 
    return Promise.resolve(true);
  },

2) 在actions.js 中检查token是否可用

 
checkToken: async ({ commit, getters }) =
> {
    //
取出token
    const token = getters.session.accessToken;
 
    if (!token) {
      //
不可用
      return Promise.resolve(false);
    }
 
    return Promise.resolve(true);
  },

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forrest Gump plus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值