• vue项目结合vuex、localstorage实现本地储存token验证登陆注册


    • 首次登录时,后端服务器判断用户账号密码正确之后,根据用户id、用户名、定义好的秘钥、过期时间生成 token ,返回给前端;
    • 前端拿到后端返回的 token ,存储在 localStroage 和 Vuex 里;
    • 前端每次路由跳转,判断 localStroage 有无 token ,没有则跳转到登录页,有则请求获取用户信息,改变登录状态;
    • 每次请求接口,在 Axios 请求头里携带 token;
    • 后端接口判断请求头有无 token,没有或者 token 过期,返回401;
    • 前端得到 401 状态码,重定向到登录页面。

    store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import VuexPersistence from 'vuex-persist'
    
    Vue.use(Vuex)
    const vuexLocal = new VuexPersistence({
      storage: window.localStorage,
      reducer: state => ({
        token: state.token, // 这个就是存入localStorage的值
        WXTempKey: state.WXTempKey
      })
    })
    const store = new Vuex.Store({
      state: {
        token: "",
        WXTempKey: '',
        isLogin: false,
        uid: 0,
        name: '',
        avatar: ''
      },
      mutations: {
        setToken(state, token) {
          state.token = token
        },
        setLogin(state, flag) {
          state.isLogin = flag
        },
        setWXTempKey(state, WXTempKey) {
          state.WXTempKey = WXTempKey
        },
      },
    
      actions: {},
      plugins: [vuexLocal.plugin]
    })
    
    export default store

     登陆页

        // 登陆方法
        async login() {
          if (!this.phone || !this.password) {
            // this.$toasted.error("请输入完善信息", { icon: "error" }).goAway(2000);
            Notify({ type: 'danger', message: "请输入完善信息", duration: 1500 })
            return;
          }
          
          try {
            // await等待一个异步返回的结果 如果没有await 会报user is undefined 获取不到
            let res = await this.http.post("/api/TokenAuth/MemberAuthenticate", {
              Phone: this.phone,
              PhoneCode: this.password,
              WXTempKey: this.$store.state.WXTempKey
                ? this.$store.state.WXTempKey
                : ""
            });
            console.log(res);
            if (res.Result) {
              // debugger
              // console.log(res);
              // localStorage.setItem("token","res.Result.AccessToken");
              this.$store.commit("setToken", res.Result.AccessToken);
              Toast({
                mask: false,
                message: '登录成功',
                position: 'bottom'
              });
              this.$router.replace({ name: "index" });
            } else {
              // this.$toasted
              //   .error(res.Error.Message, { icon: "error" })
              //   .goAway(2000);
            }
          } catch (error) {
            // this.$toasted.error(error.message, { icon: "error" }).goAway(2000);
          }
        }

    http.js

    import axios from 'axios'
    import store from './store'
    import { getToken } from '@/util/token'
    import qs from 'qs'
    import config from './config'
    import router from './router'
    import Vue from 'vue'
    import VuexPersistence from 'vuex-persist'
    import { Notify,Toast } from 'vant'
    
    console.log(config)
    
    // 创建axios实例
    const http = axios.create({
      baseURL: config.api_base,
      timeout: 15000,
     //设置请求头
      headers: {
        // 'Content-Type': 'application/x-www-form-urlencoded'
        'Content-Type' : 'application/json',
      }
    //利用qs解析json数据让后端可以解析
      transformRequest: [
          function(data, headers) {
            data = data || {}
            data = qs.stringify(data)
            return data
          }
        ]
    })
    
    // request拦截器
    http.interceptors.request.use(config => {
      config.data = config.data ? config.data : {}
      config.headers["authorization"] =store.state.token; //把token添加到请求头每次请求接口时候带上
    if(config.method=='get'){
        Toast({
          mask: false,
          message: '加载中...',
          position: 'bottom'
        });
      }else{
        Toast.loading({
          mask: true,
          message: '加载中...',
          position: 'middle',
          loadingType:'spinner'
        });
      }
      if (router.currentRoute && router.currentRoute.meta.requiresAuth) {
        if (localStorage.getItem('user')) {
          return Promise.reject('请登录后操作')
        } else {
    
          // config.headers.Authorization = token;
    
          // config.headers['authorization'] = `${store.state.token}`;
            console.log('interceptors config=',config)
          return config
        }
      } else {
        return config
      }
    })
    
    // respone拦截器
    http.interceptors.response.use(
      response => {
        let data = response.data
    
        let msg = data.message || ''
        Toast.clear();
        if (response.status === 200) {
          if (response.data.Result) {
            if (response.data.Result.Code && response.data.Result.Code !== 0) {
              Notify({ type: 'danger', message: response.data.Result.Message, duration: 1500 })
              return Promise.resolve(response.data)
            } else {
              return Promise.resolve(response.data)
            }
          }else
          {
            return Promise.resolve(response.data)   
          }
        } else {
          Notify({ type: 'danger', message: '请求失败,请稍后再试!!!', duration: 1500 })
          return Promise.reject(response)
        }
    
        // if (data.code == 401) {
        //   // 账号禁用
        //   Vue.toasted.error(data.message, { icon: 'error' }).goAway(2000)
        //   router.replace({ name: 'login' })
        //   return Promise.reject(new Error(msg))
        // } else if (data.code == 403) {
        //   // 登录失效 需重新登录
        //   Vue.toasted.error('登录失效 需重新登录', { icon: 'error' }).goAway(2000)
        //   router.replace({ name: 'login' })
        //   return Promise.reject(new Error(msg))
        // } else if (data.code == 400) {
        //   return Promise.reject(new Error(msg))
        // }
        // return data
      },
      err => {
        Toast.clear();
        if (err.response.data.Error) {
          Notify({ type: 'danger', message: err.response.data.Error.Message, duration: 1500 })
          if(err.response.status == 401 || (err.response.data.Error && err.response.data.Error.Code)){
            console.log(router)
            store.commit("setToken", '');
            router.push({
                path: "/login",
                query:{
                  redirect:router.currentRoute.fullPath
                }
            });
          }
        } else {
          Notify({ type: 'danger', message: '请求失败!!!', duration: 1500 })
        }
        return Promise.reject(err)
      }
    )
    
    export default http
  • 相关阅读:
    Java线程:线程栈模型与线程的变量
    Java线程:创建与启动
    Java线程:概念与原理
    oracle的备份与恢复
    oracle视图
    oracle PL/SQL的介绍
    Oracle掌管权限和角色
    oracle基础 管理索引
    oracle维护数据的完整性
    删除VisualStudio 2013中的 "send Feedback" 按钮
  • 原文地址:https://www.cnblogs.com/jervy/p/10115337.html
Copyright © 2020-2023  润新知