• 登录页(-- 郑郑日上项目【vue-element-admin】【PC 端】【后台管理系统】)


    (一)将 token 存储到 cookie 中

    核心实现方式: 使用 js-cookie 插件将 token 存储到 cookie 中

    1、通过 js-cookie 中的 getToken() 获取存储在 cookie 中的 token

    (-- @/store/modules/user.js;state 配置项)

    token: getToken() 
    
    • 1

    2、通过 js-cookie 中的 setToken() 将 token 存储到 cookie 中 && 将 token 存储到 state 中

    (-- 同上;mutations 配置项)

    setToken(state, token) {state.token = tokensetToken(token)
    } 
    
    • 1
    • 2

    (-- 同上;actions 配置项)

    async login(context, data) {const result = await login(data)context.commit('setToken', result)
    } 
    
    • 1
    • 2

    (-- @/views/login/index.vue)

    import { mapActions } from 'vuex'
    
    methods() {...mapActions(['user/login'])
    }
    
    async login() { // 登录-- 增await this.$store.dispatch('user/login', this.loginForm)--this.$router.push({name: 'Dashboard'})
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (二)每次发送请求时携带 token

    核心实现方式:请求拦截器中的请求头中携带 token

    (-- @/utils/request.js)

    service.interceptors.request.use(config => { // 请求拦截器-- 增if (store.getters.token) { // 在请求头中携带 tokenconfig.headers['Authorization'] = `${store.getters.token}`}--return config
    }) 
    
    • 1
    • 2

    (三)token 过期时的处理

    前端实现

    核心实现方式: 获取 token 时,将当前时间戳一起存储到缓存中。每当发起请求时,判断(当前时间戳 - 缓存中的时间戳)/ 1000 如果大于过期时间,表示 token 过期,清空 token,跳转到登录页,抛出时间戳过期提示

    1、定义时间戳的 key && 定义获取时间戳的方法 && 定义设置时间戳的方法

    (-- @/utils/auth.js)

    const timeKey = 'hrsaas-timestamp-key' // 时间戳
    
    export function getTimeStamp() { // 获取 时间戳return Cookies.get(timeKey)
    }
    export function setTimeStamp() { // 设置 时间戳Cookies.set(timeKey, Date.now())
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、获取 token 的时候将当前时间戳存到缓存中

    (-- @/views/login/index.vue)

    -- 增
    import { setTimeStamp } from '@/utils/auth'
    --
    
    async login(content, data) { // 登录...context.commit('setToken', result)-- 增setTimeStamp()--
    
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、每次请求时,调用 判断 token 是否过期的方法,如果过期则清空 token,跳转到登录页,并抛出错误

    (-- @/utils/request.js)

    -- 增
    import { getTimeStamp } from '@/utils/auto'
    import router from '@/router'
    
    const TimeOut = 3600 // token 过期时间。3600 毫秒 = 一小时
    
    function IsCheckTimeOut() { // 判断 token 是否过期var currentTime = Date.now() // 当前时间戳var timeStamp = getTimeStamp() // 缓存时间戳return (currentTime - timeStamp) / 1000 > TimeOut // 判断 token 是否过期 // 公式:【(当前时间戳 - 缓存中的时间戳)/ 1000 如果大于过期时间,表示 token 过期】。这里的除 1000 是将毫秒转化成秒。
    }
    --
    
    // 请求拦截器
    if (store.getters.token) {-- 增if (IsCheckTimeOut()) { // 判断 token 是否过期store.dispatch('user/logout') // 调用登出方法router.push('/login')return Promise.reject(new Error('token 超时了'))}--
    
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    后端实现(推荐)

    核心实现方式: 在响应拦截器中判断后端响应的状态码,如果是 401 则表示 token 过期,然后清空 token、和 vuex 中的 token 即可

    (-- @/utils/request.js)

    -- 增
    import store from '@/store'
    import router from '@/router'
    --
    
    // 响应拦截器
    service.interceptors.response.use(response => {...
    }, error => {-- 增if (error.response && error.response.data && error.response.data.code === 10002) { // 判断 token 是否过期// 调用登出方法store.dispatch('user/logout')router.push('/login')} else {-- 改(新)Message.error(error.message) // 提示错误信息--}return Promise.reject(error)---- 改(旧)Message.error(error.message) // 提示错误信息
    }) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (四)退出功能

    核心实现方式: 1、清空 state 中的 token 2、清空 cookie 中的 token 3、清空 用户信息

    (五)设置路由白名单和有 token 的情况下访问登录页直接跳转到首页

    核心实现方式: 导航守卫。在前置守卫中(判断是否有 token(如果有 token 在通过前置守卫的第一个参数判断是否访问的是 登录页,如果是登录页则调用前置守卫的第三个参数跳转到首页))

    (-- @/新建 permission.js)

    import router from '@/router'
    import nprogress from 'nprogress'
    import 'nprogress/nprogress.css' // 引入进度条样式
    import store from '@/store'
    
    const whiteList = ['/login', '/404', '/demo'] // 白名单
    
    router.beforeEach((to, from, next) => { // 前置守卫 // (参数一:将要 访问 路由的信息对象)(参数二:将要 离开 路由的信息对象)(参数三:是一个函数,表示放行,允许这次路由导航)nprogress.start() // 开启进度条if (store.getters.token) { // 判断 是否有 tokenif (to.path === '/login') { // 判断 是否前往 登录页next('/')} else {next()}} else {if (whiteList.includes(to.path)) { // 判断 前往的地址是否在白名单中next()} else {next('/login')}}nprogress.done() // 解决手动切换地址时,进度条不关闭的问题
    })
    router.afterEach(() => { // 后置守卫nprogress.done() // 关闭进度条
    }) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    Docker命令笔记
    LCD液晶显示屏常见类型和接口
    ConcurrentHashMap底层原理分析(put方法)
    Java进阶笔记(中级)
    腾讯罗嘉黎:基于APM的腾讯可观测平台技术与实践
    Tensor 的广播机制
    2022-01-29-Ajax
    信息熵和热力学定律中的熵有关系吗?
    2022.10.28 英语背诵
    JavaScript对象
  • 原文地址:https://blog.csdn.net/web2022050903/article/details/126541784