日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue项目将token存在(vuex)store和localstorage中

發(fā)布時(shí)間:2023/12/6 vue 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue项目将token存在(vuex)store和localstorage中 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

      • 一、準(zhǔn)備工作和token
          • 1、準(zhǔn)備工作
          • 2、介紹token用法
      • 二、創(chuàng)建storage,store,request
          • 1、src目錄:
          • 2、封裝storage(可選)
          • 3、創(chuàng)建store
          • 4、創(chuàng)建request
      • 三、配置代理,封裝路由router、設(shè)置路由守衛(wèi),在main.js中引入router、store
          • 一、配置代理
          • 二、封裝路由router,并設(shè)置路由守衛(wèi)
          • 三、在main.js中引入router、store
      • 四、登錄頁面實(shí)際使用

適合小白 ?

一、準(zhǔn)備工作和token

1、準(zhǔn)備工作
  • 了解(session,cookie)token
    Token的引入:Token是在客戶端頻繁向服務(wù)端請(qǐng)求數(shù)據(jù),服務(wù)端頻繁的去數(shù)據(jù)庫查詢用戶名和密碼并進(jìn)行對(duì)比,判斷用戶名和密碼正確與否,并作出相應(yīng)提示,在這樣的背景下,Token便應(yīng)運(yùn)而生。
    token 是在服務(wù)端產(chǎn)生的一串字符串,以作客戶端進(jìn)行請(qǐng)求的一個(gè)令牌。如果前端使用用戶名/密碼向服務(wù)端請(qǐng)求認(rèn)證,服務(wù)端認(rèn)證成功,那么在服務(wù)端會(huì)返回 Token 給前端。前端可以在每次請(qǐng)求的時(shí)候帶上 Token 證明自己的合法地位。如果這個(gè) Token 在服務(wù)端持久化(比如存入數(shù)據(jù)庫),那它就是一個(gè)永久的身份令牌(除非設(shè)置了有效期)。

  • token 優(yōu)點(diǎn)
    Token 完全由應(yīng)用管理,所以它可以避開同源策略
    Token 可以避免 CSRF 攻擊
    Token 可以是無狀態(tài)的,可以在多個(gè)服務(wù)間共享
    減輕服務(wù)器的壓力,減少頻繁的查詢數(shù)據(jù)庫,使服務(wù)器更加健壯。

  • 安裝vuex
    cnpm install vuex --save

2、介紹token用法

在前后端完全分離的情況下,Vue項(xiàng)目中實(shí)現(xiàn)token驗(yàn)證大致思路如下:

1、第一次登錄的時(shí)候,前端調(diào)后端的登陸接口,發(fā)送用戶名和密碼

2、后端收到請(qǐng)求,驗(yàn)證用戶名和密碼,驗(yàn)證成功,就給前端返回一個(gè)token

3、前端拿到token,將token存儲(chǔ)到localStorage和vuex中,并跳轉(zhuǎn)路由頁面

4、前端每次跳轉(zhuǎn)路由,就判斷 localStroage 中有無 token ,沒有就跳轉(zhuǎn)到登錄頁面,有則跳轉(zhuǎn)到對(duì)應(yīng)路由頁面

5、每次調(diào)后端接口,都要在請(qǐng)求頭中加token

6、后端判斷請(qǐng)求頭中有無token,有token,就拿到token并驗(yàn)證token,驗(yàn)證成功就返回?cái)?shù)據(jù),驗(yàn)證失敗(例如:token過期)就返回401,請(qǐng)求頭中沒有token也返回401

7、如果前端拿到狀態(tài)碼為401,就清除token信息并跳轉(zhuǎn)到登錄頁面
————————————————
版權(quán)聲明:本文為CSDN博主「sleepwalker_1992」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sleepwalker_1992/article/details/82974703


二、創(chuàng)建storage,store,request

1、src目錄:


注:

  • 封裝storage是可選的,不封裝就用原生的唄;創(chuàng)建store是必須的!
  • token一定要存在storage緩存中,否則刷新一下,store會(huì)重新被加載,token就沒了;
  • 那存在store是不是多余了,這個(gè)也是為了數(shù)據(jù)統(tǒng)一管理吧,也是數(shù)據(jù)可視化,因?yàn)榫彺嬷械臄?shù)據(jù)代碼中是看不見的~
2、封裝storage(可選)
// 封裝操作localstorage本地存儲(chǔ)的方法 模塊化var storage = {set(key, value) {localStorage.setItem(key, JSON.stringify(value));// localStorage.key = value;// localStorage[key] = value;},get(key) {return JSON.parse(localStorage.getItem(key));},getForIndex(index) {return localStorage.key(index);},getKeys(){let items = this.getAll();let keys = [];for (let index=0;index<items.length;index++){keys.push(items[index].key);}return keys;},getLength() {return localStorage.length;},getSupport() {return (typeof (Storage) !== "undefined") ? true : false;},remove(key) {localStorage.removeItem(key);},removeAll() {localStorage.clear();},getAll() {let len = localStorage.length; // 獲取長度let arr = new Array(); // 定義數(shù)據(jù)集for (var i = 0; i < len; i++) {// 獲取key 索引從0開始var getKey = localStorage.key(i);// 獲取key對(duì)應(yīng)的值var getVal = localStorage.getItem(getKey);// 放進(jìn)數(shù)組arr[i] = {'key': getKey,'val': getVal,}}return arr;} }export default storage;
3、創(chuàng)建store
import Vue from 'vue' import Vuex from 'vuex' import storage from '@/model/storage'Vue.use(Vuex); // 用Vuex.Store對(duì)象用來記錄token const store = new Vuex.Store({state: {// 存儲(chǔ)tokentoken:"",userName:"" // 可選},const getters = {getToken(state){return state.token || storage.get("token") || null;} }// 計(jì)算屬性mutations: {// 修改token,并將token存入localStoragesetToken(state,token) {state.token = token;storage.set('token', token);console.log('store、localstorage保存token成功!');},delToken(state) {state.token = "";storage.remove("token");},// 可選setUserInfo(state, userName) {state.userName = userName;}} });actions: {// removeToken: (context) => {// context.commit('setToken')// }},export default store;
4、創(chuàng)建request
import axios from 'axios' import store from '@/store' import router from '@/router'// create an axios instance const service = axios.create({// index.js設(shè)置了代理(解決跨域) invoice = http://58.246.79.142:25005baseURL: "/invoice", // url = base url + request urltimeout: 5000, // request timeout })//添加請(qǐng)求攔截器,若token存在則在請(qǐng)求頭中加token,不存在也繼續(xù)請(qǐng)求 service.interceptors.request.use(config => {// 每次發(fā)送請(qǐng)求之前檢測都vuex存有token,那么都要放在請(qǐng)求頭發(fā)送給服務(wù)器,沒有則不帶token// Authorization是根據(jù)后端自定義字段config.headers.Authorization = store.getters.getToken;return config;},error => {console.log("在request攔截器顯示錯(cuò)誤:", error.response)return Promise.reject(error);} );//respone攔截器 service.interceptors.response.use(response => {// 在status正確的情況下,code不正確則返回對(duì)應(yīng)的錯(cuò)誤信息(后臺(tái)自定義為200是正確,并且將錯(cuò)誤信息寫在message),正確則返回響應(yīng)return response.data.code == 200 ? response : Promise.reject(response.data.message);},error => { // 在status不正確的情況下,判別status狀態(tài)碼給出對(duì)應(yīng)響應(yīng)if (error.response) {console.log("在respone攔截器顯示錯(cuò)誤:", error.response)switch (error.response.status) {case 401://可能是token過期,清除它store.commit("delToken");router.replace({ //跳轉(zhuǎn)到登錄頁面path: '/login',// 將跳轉(zhuǎn)的路由path作為參數(shù),登錄成功后跳轉(zhuǎn)到該路由query: { redirect: router.currentRoute.fullPath }});}}return Promise.reject(error.response.data);} );export default service

三、配置代理,封裝路由router、設(shè)置路由守衛(wèi),在main.js中引入router、store

一、配置代理

二、封裝路由router,并設(shè)置路由守衛(wèi)
/* eslint-disable */ import Vue from 'vue' import Router from 'vue-router' import Main from '@/main/index'import store from '@/store' import storage from '@/model/storage'Vue.use(Router)const routes = [{path: '/',name: 'Main',redirect: '/login',// 某些頁面規(guī)定必須登錄后才能查看 ,可以在router中配置meta,將需要登錄的requireAuth設(shè)為true,meta: {requireAuth: true,}},{path: '/login',component: () => import('@/views/login'),},{path: '/invoice',redirect: '/invoice',component: Main,},]},{path: '*',component: Main} ]const router = new Router({ routes: routes })// 設(shè)置路由守衛(wèi),在進(jìn)頁面之前,判斷有token,才進(jìn)入頁面,否則返回登錄頁面 if (storage.get("token")) {store.commit("setToken", storage.get("token")); } router.beforeEach((to, from, next) => {// 判斷要去的路由有沒有requiresAuth// to.matched.some(r => r.meta.requireAuth) or to.meta.requiresAuthif (to.matched.some(r => r.meta.requireAuth)) {if (store.state.token) {next(); //有token,進(jìn)行request請(qǐng)求,后臺(tái)還會(huì)驗(yàn)證token} else {next({path: "/login",// 將剛剛要去的路由path(卻無權(quán)限)作為參數(shù),方便登錄成功后直接跳轉(zhuǎn)到該路由,這要進(jìn)一步在登陸頁面判斷query: { redirect: to.fullPath } });}} else {next(); //如果無需token,那么隨它去吧} });export default router
三、在main.js中引入router、store
import Vue from 'vue' import App from './App' import router from './router'import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css' import store from '@/store'// 兼容ie // import 'babel-polyfill';Vue.use(ElementUI); Vue.config.productionTip = falsenew Vue({el: '#app',router:router,store,components: { App },template: '<App/>' })

四、登錄頁面實(shí)際使用

只給出表單提交示例函數(shù)和依賴js

import { postLogin } from "@/api/login";submitForm(formName) {this.$refs[formName].validate(valid => {if (valid) {let that = this;// console.log('username',this.loginForm.username)// 通過校驗(yàn)規(guī)則后進(jìn)入校驗(yàn)用戶名密碼是否正確// 沒有后臺(tái)接口可以自定義一個(gè)函數(shù)來模擬,替換postLoginpostLogin(this.loginForm.username, this.loginForm.password).then(res => {console.log(res);that.$store.commit("setToken", res.data.token);that.$store.commit("setUserInfo", res.data.account);this.$notify({title: "登錄成功",type: "success",showClose: false,duration: 1000});setTimeout(() => {// 此時(shí)要判斷/login后面的參數(shù),若無參數(shù),進(jìn)入主頁;this.$router.push("/index");// 若有參數(shù)則參數(shù)為未有權(quán)限的那個(gè)路由,跳轉(zhuǎn)到那個(gè)路由// this.$router.push(***); -- 具體要自己在這實(shí)現(xiàn)}, 1000);}).catch(error => {// 錯(cuò)誤分為 status-請(qǐng)求錯(cuò)誤 和 code-賬號(hào)密碼錯(cuò)誤this.$message.error(error);console.log(error);});} else {// 不符合前端校驗(yàn)this.$message.error('format error:'+error);console.log('format error:',error);return false;}});}

上面依賴的@/api/login:

import request from '@/utils/request.js' // 前面封裝的request // 在request中,設(shè)置了根路徑/invoice,所以每一個(gè)請(qǐng)求都會(huì)自動(dòng)在前面帶上invoice; // 由于在config中的index配置過了代理(監(jiān)聽)的路徑也是/invoice,但凡遇到/invoice路徑就會(huì)替換為target目標(biāo)地址(后臺(tái)接口根地址) // 實(shí)現(xiàn)跨域,即不限于只能訪問根路徑為127.0.0.1下的地址 export function postLogin(account,password) {console.log(account,password)return request({url: '/login',method: 'post',params:{// 具體傳參(鍵)要看后臺(tái)要求account:account,password:password}}) }

總結(jié)

以上是生活随笔為你收集整理的vue项目将token存在(vuex)store和localstorage中的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。