通过vuex存储token,通过前置路由守卫完成对登录操作之后的token值验证,完成登录状态的保持

发布于:2022-12-19 ⋅ 阅读:(578) ⋅ 点赞:(0)

通过vuex存储token,通过前置路由守卫完成对登录操作之后的token值验证,完成登录状态的保持

在这里插入图片描述

  • 账号和密码正确,则需要来保持用户的登录状态而前后端分离如何保存登录状态
  • 保持用户的登录状态 cookie/session [考虑到跨域问题]
  • 前后端分离保持用户登录状态的方案 token
  • token是后端返回给前端一个加密后的字符串,需要在本地进行保存
  • token存储在vuex中,对于vuex中需要持久化的内容可以存储在本地浏览器中

一、除过登录路由,在其他路由跳转之时判断token值是否存在。

全局前置路由守卫

每次路由跳转之前触发:
一般可以通过元信息来判断,哪些路由可以不登录就可以访问,那些路由需要这个token才能访问,当然也可以用地址

router.beforeEach((to,from,next)=>{
    console.log("to",to.meta);
    console.log("from",from);
    if(to.path != '/login'){
         next({
            path: '/admin/staff',
            replace: true
        })
    }else{
        next()
    }
})

通过在路由中添加met元信息来判断访问那些路由需要登录之后(有token值)才能验证访问,

router.beforeEach((to,from,next)=>{
    console.log("to",to.meta);
    console.log("from",from);
    if(to.meta.istoken){
         next({
            path: '/',
            replace: true
        })
    }else{
        next()
    }
   
})

那么如何去存储这个token值呢。

对token不了解的话可以看这篇token描述已经应用场景
首先能想到的是在这个全局的登录之后各个页面(大部分)是需要这个鉴权验证,也就是对当前用户的判定,也就是生成一个唯一的token值,在后面的每次http访问都带上:

  • 那我们这能想到的是除了登陆请求,在请求拦截器中对所有的请求添加 token 请求字段
import axios from 'axios'
const instance = axios.create()
//把get暂时存在sessionStoring中
//给请求头添加token。
instance.interceptors.request.use(config => {
  config.url != '/api/login' ? (config.headers.token = store.getters.token) : null
  return config
})

这里通过express框架,搭建一个简易服务器,针对一路由请求对token是否存在的进行判断,

let allows = [
    '/api/login',
    '/api/upfile'
]
module.exports = (req, res, next) => {
    let token = req.headers.token || ''
    if (!allows.includes(req.path)) {
        if (token == '') {
            res.send({
                code: 1000,
                msg: 'token无效',
                data: null
            })
            return;
        }
        // 如果token存在,进行解密,得到明文
        // 明文中一般会有账号和对应的用户id信息,用此信息在数据表中去查询,如果存在,则返回数据,不存在返回,没有授权
        next()
    }
    next()
}
*******************************************
const checkToken = require('./middleware')
app.use(checkToken);

考虑到:那这个token其实需要在全局的的组中都需要用到,就把它放在vuex中,
并想到数据持久化。
在给vuex传入的同时,进行本地存储;

import {
    doLoginApi
} from '@/api/userApi'
import Store from '@/utils/store'
import {
    hasToken
} from '@/utils/token'
const sessionStore = new Store()

export default {
    state: {
        token: '',
        nickname: ''
    },
    mutations: {
        // 写入vuex的同时,进行本地存储,为了持久化
        setUserLoginInfo(state, payload) {
            state.token = payload.token
            state.nickname = payload.nickname;
            !hasToken() && setStorage(payload)
        },
        userLogout(state, payload) {
            state.token = ''
            state.nickname = ''
            sessionStore.remove('token')
            sessionStore.remove('nickname')
            window.location.href = '/login'
        }
    },
    actions: {
        // 进行网络请求的调用,验证账号和密码是否正确
        async fetchUserLogin({
            commit
        }, payload) {
            let ret = await doLoginApi(payload)
            // 通知vuex中的state来修改对应的token数据
            commit('setUserLoginInfo', ret.data)
            return ret.code
        }
    }
}


function setStorage({
    token,
    nickname
}) {
    sessionStore.set('token', token)
    sessionStore.set('nickname', nickname)
}

针对本地存储封装成一个类导出:

class Store {
    // attrname 它是 sessionStorage 还是  localStorage
    // constructor(attrName = 'sessionStorage') {
    // session / local
    constructor(attrName = 'session') {
        this.attrName = attrName + 'Storage'
    }
    set(key, value) {
        if (typeof value == 'object') {
            value = JSON.stringify(value)
        }
        // sessionStorage.setItem(key, value)
        window[this.attrName].setItem(key, value)
    }

    get(key, defaultValue = '') {
        let value = window[this.attrName].getItem(key)
        value = value ? value : defaultValue
        value = /[\[\{]/.test(value) ? JSON.parse(value) : value
        return value
    }

    remove(key) {
        window[this.attrName].removeItem(key)
    }
}

// export default new Store()
export default Store

网站公告

今日签到

点亮在社区的每一天
去签到