Front-end login and exit: handling Token issues (acquisition, caching, invalidation processing) and code implementation

1. What is Token?

Token is a string of characters generated by the server. When the user successfully logs in for the first time, the server will generate a token and return it to the client.
When the user requests data from the server again, he only needs to carry the token to request data, without logging in with the user name and password again. Purpose: Using tokens to intercept data
can
reduce the number of database requests and relieve server pressure.

2. Obtain token

When the user successfully logs in for the first time, the backend will return a token to the client. The frontend caches the token locally, and then needs to bring the token in the header every time a request is made. At this time, the local token and the backend database The token is verified. If the two are consistent, the request succeeds, otherwise it fails.
Insert image description here

3. Token invalidation handling

Since the front and back ends interact through tokens, if it is always valid, there will be security risks, so we need to check the token time on the client.
The server's token is generally not set too long. According to the actual situation, it is usually 1-7 days, and there is no token. It is permanent. A permanent token is equivalent to a series of permanent keys and is insecure.

There are generally two scenarios for token expiration:
① Active logout: The user logs out after clicking the logout button
② Passive logout: The token expires, or someone logs out by "invoking the account"

important point

No matter how you exit the token, the operations that need to be performed when the user exits are fixed:
1. Clear the cached data of the current user
2. Clear the configuration of relevant permissions
3. Return to the login page

1. Take the initiative to exit

The user actively clicks to exit the function to implement
user.js

// 获取退出登录
logout(context) {
    
    
  context.commit("removeToken"); // 删除token
  context.commit("reomveUserInfo"); // 删除用户信息
},

2. Token expires

① Logic diagram

Insert image description here

②Plan

When the user logs in, record the current login time
and set a token aging time
. When the interface is called, compare the login time according to the current time to see if the aging time has been exceeded
. If it has not been exceeded, follow-up operations will be performed normally. If it is exceeded, log out. operate

③Code implementation

user.js

// 获取登录信息
async login(context, data) {
    
    
  const result = await loginInfo(data);
  context.commit("setToken", result);
  setTimeStamp(); // 写入时间戳
},

auth.js

import Cookies from "js-cookie";
const timeKey = 'liqi6limi-timestamp-key' // 设置一个独一无二的key

// 获取时间戳
export function getTimeStamp() {
    
    
  return Cookies.get(timeKey)
}
// 设置时间戳
export function setTimeStamp() {
    
    
  Cookies.set(timeKey, Date.now())
}

// 设置超时时间
export const TimeOut = 3600; 

// 是否超时
export function IsCheckTimeOut() {
    
    
  var currentTime = Date.now(); // 当前时间戳
  var timeStamp = getTimeStamp(); // 缓存时间戳
  return (currentTime - timeStamp) / 1000 > TimeOut;
}

request.js

import store from "@/store";
import axios from "axios";
import {
    
     getTimeStamp,IsCheckTimeOut } from "@/utils/auth";
import router from "@/router";

// 创建axios实例
const service = axios.create({
    
    
  baseURL: "/api",
  timeout: 5000,
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    
    
    // 是否存在token
    if (store.getters.token) {
    
    
      if (IsCheckTimeOut()) {
    
    
        store.dispatch("user/logout"); // 退出登录的action
        router.push("/login"); // 跳转到登录页
        return Promise.reject(new Error("token超时了")); // 抛出的错误,会在响应拦截器的错误捕捉中捕捉到
        console.log("超时");
      }
      config.headers["Authorization"] = `Bearer ${
      
      store.getters.token}`; // 如果token存在 注入token
    }
    return config; // 必须返回配置
  },
  (error) => {
    
    
    return Promise.reject(error);
  }
);

3. Being called a number

① Logic diagram

Insert image description here

② Plan

When the backend returns data, it will return a specific status code to notify the frontend.
When the frontend receives a specific status code, it means that it has encountered a specific state: log out at this time.

③Code implementation

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    
    
    // axios默认加了一层data
    const {
    
     success, message, data } = response.data;
    //   要根据success的成功与否决定下面的操作
    if (success) {
    
    
      return data;
    } else {
    
    
      // 业务已经错误了 
      Message.error(message); // 提示错误消息
      return Promise.reject(new Error(message));
    }
  },
  (error) => {
    
    
    // error 信息 里面 response的对象
    if (
      error.response &&
      error.response.data &&
      error.response.data.code === 10002
    ) {
    
    
      // 当等于10002的时候 表示 后端告诉我token超时了
      store.dispatch("user/logout"); // 登出action 删除token
      router.push("/login");
    } else {
    
    
      Message.error(error.message); // 提示错误信息
    }
    return Promise.reject(error);
  }
);

Guess you like

Origin blog.csdn.net/Vest_er/article/details/127696264