简易的登录权限判断

这篇博客介绍了如何实现登录权限判断,包括服务器端登录接口的创建、登录获取token、使用vuex存储token以及路由权限的登录判断。通过模拟数据和axios请求,展示了登录流程的关键步骤,并使用路由守卫进行权限控制。
摘要由CSDN通过智能技术生成

这篇博客记录一下如何实现一个简单的登录权限判断,由于入行时间不长,因此对权限相关知识的理解浅薄,如有幸被大佬看到,希望大佬不吝赐教。
实现简单的登录权限判断主要分四个步骤。

  1. 登录服务器端实现以及登录接口实现
  2. 登录获取token
  3. store与本地存储token
  4. 路由权限登录判断

接下来我将依次实现上述步骤。

1. 登录服务器端实现以及登录接口实现

要实现一个登录页面首先需要一个登录的请求接口,因此我们模拟服务器端发送一个axios请求。

这里我们准备了两个json格式的文件admin_login.jsonvip_login.json

admin_login.json代码如下:

{
  "code": 0,
  "message": "登录成功",
  "data": {
    "token": "admin"
  }
}

vip_login.json代码如下:

{
  "code": 0,
  "message": "登录成功",
  "data": {
    "token": "vip"
  }
}

如果登录请求url的user参数是amdin,则响应admin_login.json对应的json数据,否则响应vip_login.json对应的json数据。注意,这里为了简化流程,并没有使用jwt实现动态的token

有了响应数据,下面我们实现登录请求接口。

// 服务器端
const express = require("express");
const app = new express();
const vipLogin = require("./data/vip_login.json");
const adminLogin = require("./data/admin_login.json");
const url = require("url");

// 登录接口
app.get("/login", (req, res) => {
  // 调用query可以使用query对象内的属性
  const user = url.parse(req.url, true).query.user;
  // 如果请求的url参数是admin,返回admin对应的json数据
  if (user === "admin") {
    res.send(adminLogin);
  } else {
    res.send(vipLogin);
  }
});

app.listen(3000, () => {
  console.log("服务器运行在http://localhost:3000");
});

这里涉及到url.parse(param1,param2)方法,我们稍作讲解。

该方法可以解析url,可以把query参数解析成键值对形式的数值保存内容,param1表示请求的url,param2是布尔值,表示是否将query参数转成一个query对象,url.parse(param1,param2).query.属性名可以获取请求url的参数的具体值。

2. 登录获取token

封装axios请求

// 用于封装axios
import axios from "axios";
import store from "@/store/index";

const http = {};

let instance = axios.create({
  timeout: 5000,
  // baseURL:"http://locahost:3000"
});

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
    // 请求头添加token
    // if (store.state.UserToken) {
    //   config.header.Authorization = store.state.UserToken;
    // }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

// 响应拦截器即异常处理
instance.interceptors.response.use((response) => {
    return response.data;
  },(err) => {
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = "请求出错";
          break;
        case 401:
          Message.warning({
            message: "授权失败,请重新登录",
          });
          store.commit("LOGIN_OUT");
          setTimeout(() => {
            window.location.reload();
          }, 1000);

          return;
        case 403:
          err.message = "拒绝访问";
          break;
        case 404:
          err.message = "请求错误,未找到该资源";
          break;
        case 500:
          err.message = "服务器端出错";
          break;
      }
    } else {
      err.message = "连接服务器失败";
    }
    Message.error({message: err.message});
    return Promise.reject(err.response);
  }
);

http.get = function (url, options) {
  return new Promise((resolve, reject) => {
    instance.get(url, options).then((response) => {
        if (response.code === 0) {
          resolve(response.data);
        } else {
          Message.error({ message: response.message,});
          reject(response.message);
        }
      }).catch((e) => {console.log(e);});
  });
};

定义登录接口

import axios from "../utils/http";

// 登录接口
export function login(user) {
  return axios.get("/api/login?user=" + user);
}

跨域的处理方式
后台:cors
前台:proxy开发环境下配置代理 这里我们使用这种方式
修改vue.config.js配置文件如下。

const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
  proxy: {
    "/api": {
      target: "http://localhost:3000",
      changeOrigin: true,
      pathRewrite: {
        "^/api": "",
      },
    },
  },
},
});

修改配置后,记得重启服务器。
下面我们实现一个简易的登录页面来验证是否能通过接口成功获取token。
login/index.vue

<template>
  <div class="container">
    <div class="login">
      <div class="main">
        <div class="account">
          <span>账号:</span>
          <input type="text"  placeholder="随便输" name="account" v-model.trim="account" />
        </div>
        <div class="password">
          <span>密码:</span>
          <input type="password" placeholder="随便输" name="password" v-model.trim="password" @keyup.enter="login" />
        </div>
        <p class="loginBtn">
          <button id="loginBtn" @click="login">登录</button>
        </p>
      </div>
    </div>
  </div>
</template>

<script>
import { login } from "../../api";
export default {
  data() {
    return {
      account: "",
      password: "",
    };
  },
  mounted() {},
  methods: {
    async login() {
      let data = await login(this.account);
      let token = data.token;
      console.log("当前token为:", token);
      // this.$store.commit("LOGIN_IN", token);
      // this.$router.replace("/");
    },
  },
};
</script>

<style scoped>
.container {
  background-color: #2b4b6b;
  width: 100%;
  height: 100%;
}
.login {
  width: 450px;
  height: 300px;
  background-color: #fff;
  border-radius: 10px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.main {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
</style>

可以看到成功获取token。
在这里插入图片描述

3. store与本地存储token

我们使用vuex实现保存token至本地缓存。
store/defaultState.js

export default {
  get UserToken() {
    return localStorage.getItem("token");
  },
  set UserToken(value) {
    localStorage.setItem("token", value);
  },
};

store/mutation.js

export default {
  LOGIN_IN(state, token) {
    state.UserToken = token;
  },
  LOGIN_OUT(state) {
    state.UserToken = "";
  },
};

store/index.js

import Vue from "vue";
import Vuex from "vuex";
import state from "./defaultState";
import mutations from "./mutations";
Vue.use(Vuex);

export default new Vuex.Store({
  state,
  mutations,
});

修改login/index.vue的login方法如下:

methods: {
    async login() {
      let data = await login(this.account);
      let token = data.token;
      // console.log("当前token为:", token);
      this.$store.commit("LOGIN_IN", token);
      // this.$router.replace("/");
    },
  },

验证结果如下:
在这里插入图片描述

4. 路由权限登录判断

我们通过路由守卫实现权限判断。
实现路由守卫

import router from "./index";
import store from "@/store/index";

// 路由守卫
router.beforeEach((to, from, next) => {
  if (!store.state.UserToken) {
    // Usertoken不存在表示未登录=>页面是否需要登录
    // to.matched该数组中保存着匹配到的所有路由信息
    if (
      to.matched.length > 0 &&
      !to.matched.some((record) => record.meta.requiresAuth)
    ) {
      // 如果路由信息数组存在,并且不存在需要登录后才能进入的路由时,跳转下一路由
      next();
    } else {
      // 路由信息数组不存在或者 存在需要登录后此案进入的路由时,跳转登录页面路由
      next({
        path: "/login",
      });
    }
  } else {
    // 用户已经登录,处理路由的访问权限,跳转下一路由
    next();
  }
});

实现路由守卫的代码中涉及到to.matched()方法,了解此方法可以参考以下博客。

route中的to.matched的运用

修改login/index.vue的login方法如下:

methods: {
    async login() {
      let data = await login(this.account);
      let token = data.token;
      // console.log("当前token为:", token);
      this.$store.commit("LOGIN_IN", token);
      this.$router.replace("/");
    },
  },

最后我们验证一下
在这里插入图片描述
小知识点总结:

  1. to.matched
  2. array.some
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值