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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue项目使用拦截器和JWT验证 完整案例

發布時間:2023/12/8 vue 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue项目使用拦截器和JWT验证 完整案例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

挺詳細的一個案例項目,值得參考!


作者:YXi

https://juejin.im/post/6844903959883218951)

https://gitee.com/gitee_fanjunyang/Inter_JWT

幾乎在所有的項目中都離不開攔截器登錄驗證,這是必需的。如果你學會了這個 demo,那么幾乎所有網站的登錄驗證,加載動畫就都會了,所以背也要背會

所以本章以一個 demo 為例,來幫助大家理解攔截器登錄驗證控制

文章后面有源碼,可以下載下來運行一下

先來看看效果:

功能:

  • 當你訪問首頁的時候,會有一個加載動畫,就是攔截器的功勞,并且首頁會有一個當前登錄的用戶名,默認是 wangcai,等你登錄成功后,會替換成你自己登錄的用戶名

  • 當你沒有登錄的時候,可以訪問首頁和登錄頁,但是訪問不了個人中心 (Profile),當你訪問個人中心,會給你自動跳轉到登錄頁

  • 當你在登錄頁進行登錄,如果用戶名輸入錯誤的話,會彈出錯誤信息

  • 當你輸入正確的時候 (我設置了 Fan 為正確的用戶名),點擊登錄,登錄成功后,會自動給你跳轉到首頁

  • 并且登錄成功后,如果你再點擊想進入登錄頁,是不行的,他會自動給你跳轉到首頁

  • 登錄成功后,就可以訪問 個人中心頁面

  • 如果你超過 20 秒 不對頁面進行操作 (我設置的是 20 秒,可以自行設置),那么 token 會自動失效,那么你就訪問不了個人中心,你需要再次登錄

  • 如果你在 20 秒 之內,操作頁面的話,那么 token 的值是不會失效的,所以是不需要再次登錄的。也就是說,在 20 秒 之內,你每次進行路由跳轉的時候,token 的值和時間就會自動重置,防止失效讓你再次登錄(總不能讓你看著看著突然讓你登錄)

  • 搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

下面就讓我們開始吧!!!(有關代碼的解釋說明已在代碼中注釋

案例

使用攔截器并封裝axios

新建一個 Vue 項目 (vue create demo)

刪去不必要的文件和代碼,經典化代碼

安裝需要的依賴:

package.json文件部分代碼:

"dependencies": {"axios": "^0.19.0","body-parser": "^1.19.0","core-js": "^2.6.5","express": "^4.17.1","iview": "^4.0.0-rc.4","jsonwebtoken": "^8.5.1","vue": "^2.6.10","vue-router": "^3.0.3","vuex": "^3.0.1" },

在server.js文件中配置跨域,并書寫測試接口:

let express = require('express') let bodyParser = require('body-parser')let app = express()// 配置跨域 app.use((req, res, next) => {res.header("Access-Control-Allow-Origin", "\*");res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"),res.header("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization")if (req.method.toLowerCase() === "options") {return res.end();}next(); })// 配置bodyparser app.use(bodyParser.json())app.get("/user", (req, res) => {//在請求數據時,要加一個動畫,為了測試,所以讓它時間長點,加了一個定時器setTimeout(() => {res.json({name: "wangcai"})}, 500) })app.listen(3000)

在router.js中配置路由:

routes: \[{path: '/',name: 'home',component: Home},{path: '/login',name: 'login',component: () => import('./views/Login.vue')},{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue')} \]

因為項目中需要用到樣式什么的,這里我引入了iView,main.js代碼:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css'; Vue.use(iView)Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App) }).$mount('#app')

因為項目中要用到加載數據的動畫,所以需要在store.js中的state中配置:

state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;} },

在App.vue中配置跳轉:

<template><div><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template>

Home.vue代碼:

<template><div><h1>首頁面</h1></div> </template>

Login.vue代碼:

<template><div><i-input placeholder="請輸入用戶名..."></i-input><i-button type="primary">登錄</i-button></div> </template>

Profile.vue代碼:

<template> <div><h1>個人中心</h1> </div> </template>

然后在libs文件夾下面新建一個ajaxRequest.js文件,用來封裝我們自己的 axios 和 加載動畫 等

搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

import axios from 'axios' import store from '../store'//當第一次請求時,顯示loading class AjaxRequest {//當new的時候,調用這個方法constructor() {//請求的基礎路徑this.baseURL = process.env.NODE\_ENV == "production" ? "/" : "http://localhost:3000"this.timeout = 3000 //超時時間this.queue = {} //存放每一次的請求}//定義一個方法,把options展開merge(options) {return {...options,baseURL: this.baseURL,timeout: this.timeout}}//封裝一個攔截方法setInterceptor(instance, url) {//請求攔截,每次請求時,都要加上一個loading效果instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = 'xxx'//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config})//響應攔截instance.interceptors.response.use((res) => {//刪除queue里面的鏈接,如果同一個按鈕,你一秒之內點擊無數次,但是他只處理第一次操作delete this.queue\[url\]//隱藏loading動畫if (Object.keys(this.queue).length === 0) {store.commit('hideLoading')}//返回的結果return res.data})}request(options) {let instance = axios.create() //創建一個axios實例this.setInterceptor(instance, options.url) //設置攔截let config = this.merge(options)return instance(config) //axios執行后,返回promise} }export default new AjaxRequest;

然后在api文件夾下新建一個user.js文件用來放用戶相關的調用接口的方法(當你想要調用接口的時候,直接調用里面的方法就好):

import axios from '../libs/ajaxRequset'// 用戶相關的接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }

修改Home.vue中的代碼:

<template><div><h1>首頁面</h1><p>當前登錄的用戶名是{{$store.state.username}}</p></div> </template><script> //如果用export導出的話,要用這種形式,相當于解構賦值 import {getUser} from '../api/user' export default {name:'home',async mounted(){let r = await getUser()console.log(r);} } </script>

修改App.vue中的代碼(加動畫效果):

<template><div><Spin size="large" fix v-if="$store.state.isShowLoading">加載中...</Spin><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template><style> #app {font-family: "Avenir", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50; } #nav {padding: 30px; }#nav a {font-weight: bold;color: #2c3e50; }#nav a.router-link-exact-active {color: #42b983; } </style>

運行效果:

使用 JWT

在server.js中新增代碼,使用 JWT,并寫好登錄和驗證的接口:

let jwt = require('jsonwebtoken')let secret = "xwc"//登錄的接口 app.post('/login',(req,res)=>{let {username} = req.body;if(username === 'Fan'){//登錄成功后返回一個tokenres.json({code:0,username:'Fan',token:jwt.sign({username:'Fan'},secret,{expiresIn:20 //表示token20秒過期})})}else{//登錄失敗res.json({code:1,data:'登錄失敗了'})} })//驗證token的接口 app.get('/validate',(req,res)=>{let token = req.headers.authorization; //我們會把token放到我們自己設置的http的頭authorization中,在這里可以直接拿到jwt.verify(token,secret,(err,decode)=>{ //驗證tokenif(err){return res.json({code:1,data:'token失效了'})}else{// token合法 在這里,需要把token的時效延長,//總不能我們看著看著突然讓我們重新登錄,token過期的意思是,你在這之間不進行任何操作才會過期res.json({code:0,username:decode.username,token:jwt.sign({username:'Fan'},secret,{ //合法時,我們需要重新生成一個token,我們每次切換路由,都要重新生成一個tokenexpiresIn:20})})}}) })

接著在api文件夾下的user.js文件中添加登錄和驗證的方法:

import axios from '../libs/ajaxRequest'// 用戶相關的接口// 調獲取用戶信息的接口 向外暴露一個getUser方法 這個方法中調了接口 // 在組件中,就可以使用getUser,就相當于調用接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }// 再向外暴露一個登錄的方法,方法內部也是調接口 // 在登錄組件中就可以調用Login方法,需要給方法傳遞一個用戶名 export const login = (username)=>{return axios.request({url:'/login',method:'post',data:{username}}) }//驗證token方法 export const validate = ()=>{return axios.request({url:'/validate',method:'get'}) }

接著我們在lib文件夾下新建一個local.js文件,用來設置或者獲取localStorage里的token:

//把獲得到的token存到localStorage里 export const setLocal = (key,value)=>{if(typeof value == 'object'){ //如果傳過來的是對象,則轉換成字符串value = JSON.stringify(value)}localStorage.setItem(key,value) //存到localStorage里 }//獲取localStorage里的token export const getLocal = (key)=>{return localStorage.getItem(key) }

然后修改store.js中的代碼:

import Vue from 'vue' import Vuex from 'vuex' import {login,validate} from './api/user' //必須用這種方式引入 import {setLocal} from './libs/local' //引入lib文件夾下的local.js文件中的setLocal方法(往localStorage里存放token)Vue.use(Vuex)export default new Vuex.Store({state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;},//定義修改用戶名的方法setUser(state,username){state.username = username}},// actions存放接口的調用 dispatch actions里面放方法actions: {//這里面所有的方法都是異步的//登錄方法async toLogin({commit},username){let r = await login(username) //調用user.js中的login方法,也就是調用登錄接口// console.log(r);if(r.code === 0){ //登錄成功后會給你返回json數據,里面有code//登錄成功了commit('setUser',r.username) //修改用戶名setLocal('token',r.token) //把得到的token存到localStorage里}else{// console.log('............');return Promise.reject(r.data); //如果失敗,返回一個promise失敗態}},//驗證token方法async validate({commit}){let r = await validate(); //調用user.js中的validate方法,也就是調用驗證接口if(r.code === 0){commit('setUser',r.username)setLocal('token',r.token) //我們說了,驗證通過,或者每次切換路由時,都要重新生成token}return r.code === 0; //返回token是否失效,true或者false}} })

修改Login.vue中的代碼:

<template><div><i-input v-model="username" placeholder="請輸入用戶名..."></i-input><i-button type="primary" @click="login()">登錄</i-button></div> </template><script> import {mapActions} from 'vuex' //使用vuex中的mapActions方法,不會的請參考我的文章vuex的使用方法 export default {data(){return{username:'' //定義一個用戶名}},methods:{...mapActions(\['toLogin'\]), //獲取store.js文件中的actions中的toLogin方法login(){// console.log(this\['toLogin'\](this.username));//使用獲取到的toLogin方法this\['toLogin'\](this.username).then(data=>{ //因為toLogin返回的是一個Promise,所以可以.thenthis.$router.push('/') //登錄成功,跳到首頁面},err=>{this.$Message.error(err)})}} } </script>

別忘了修改ajaxRequest.js文件,在請求攔截的時候,需要加個頭,前面我們寫死了,這里,要把 token 給他,然后每次路由跳轉訪問頁面的時候,都會帶上這個頭,用來驗證:

import {getLocal} from "../libs/local" //引入//請求攔截,每次請求時,都要加上一個loading效果 instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = getLocal('token')//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config })

接著在router.js中設置路由:
哪個頁面需要登錄后才能訪問的話,給這個路由添加meta,假如我的 個人中心頁面 需要登錄后才能訪問,那么我需要修改代碼:

{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue'),meta:{needLogin:true} }

最后修改main.js中的代碼,當切換路由時,進行驗證:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css';Vue.use(iView)Vue.config.productionTip = false//每一次切換路由時,都執行這個導航守衛 router.beforeEach(async (to,from,next)=>{let isLogin = await store.dispatch('validate') //判斷是否登錄了// needLogin 表示哪些路由需要在登錄條件下才能訪問console.log(to);let needLogin = to.matched.some(match=>match.meta.needLogin)if(needLogin){//需要登錄if(isLogin){//登錄過了next()}else{//沒有登錄next('/login')}}else{//不需要登錄if(isLogin && to.path === '/login'){ //如果你訪問login頁面,則給你跳到首頁面,因為不需要登錄next('/')}else{next()}} })new Vue({router,store,render: h => h(App) }).$mount('#app')

有關需要注意的點,都加注釋了,好好看注釋就行

至此,整個案例就結束了

?

挺詳細的一個案例項目,值得參考!


作者:YXi

https://juejin.im/post/6844903959883218951)

幾乎在所有的項目中都離不開攔截器登錄驗證,這是必需的。如果你學會了這個 demo,那么幾乎所有網站的登錄驗證,加載動畫就都會了,所以背也要背會

所以本章以一個 demo 為例,來幫助大家理解攔截器登錄驗證控制

文章后面有源碼,可以下載下來運行一下

先來看看效果:

功能:

  • 當你訪問首頁的時候,會有一個加載動畫,就是攔截器的功勞,并且首頁會有一個當前登錄的用戶名,默認是 wangcai,等你登錄成功后,會替換成你自己登錄的用戶名

  • 當你沒有登錄的時候,可以訪問首頁和登錄頁,但是訪問不了個人中心 (Profile),當你訪問個人中心,會給你自動跳轉到登錄頁

  • 當你在登錄頁進行登錄,如果用戶名輸入錯誤的話,會彈出錯誤信息

  • 當你輸入正確的時候 (我設置了 Fan 為正確的用戶名),點擊登錄,登錄成功后,會自動給你跳轉到首頁

  • 并且登錄成功后,如果你再點擊想進入登錄頁,是不行的,他會自動給你跳轉到首頁

  • 登錄成功后,就可以訪問 個人中心頁面

  • 如果你超過 20 秒 不對頁面進行操作 (我設置的是 20 秒,可以自行設置),那么 token 會自動失效,那么你就訪問不了個人中心,你需要再次登錄

  • 如果你在 20 秒 之內,操作頁面的話,那么 token 的值是不會失效的,所以是不需要再次登錄的。也就是說,在 20 秒 之內,你每次進行路由跳轉的時候,token 的值和時間就會自動重置,防止失效讓你再次登錄(總不能讓你看著看著突然讓你登錄)

  • 搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

下面就讓我們開始吧!!!(有關代碼的解釋說明已在代碼中注釋

案例

使用攔截器并封裝axios

新建一個 Vue 項目 (vue create demo)

刪去不必要的文件和代碼,經典化代碼

安裝需要的依賴:

package.json文件部分代碼:

"dependencies": {"axios": "^0.19.0","body-parser": "^1.19.0","core-js": "^2.6.5","express": "^4.17.1","iview": "^4.0.0-rc.4","jsonwebtoken": "^8.5.1","vue": "^2.6.10","vue-router": "^3.0.3","vuex": "^3.0.1" },

在server.js文件中配置跨域,并書寫測試接口:

let express = require('express') let bodyParser = require('body-parser')let app = express()// 配置跨域 app.use((req, res, next) => {res.header("Access-Control-Allow-Origin", "\*");res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"),res.header("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization")if (req.method.toLowerCase() === "options") {return res.end();}next(); })// 配置bodyparser app.use(bodyParser.json())app.get("/user", (req, res) => {//在請求數據時,要加一個動畫,為了測試,所以讓它時間長點,加了一個定時器setTimeout(() => {res.json({name: "wangcai"})}, 500) })app.listen(3000)

在router.js中配置路由:

routes: \[{path: '/',name: 'home',component: Home},{path: '/login',name: 'login',component: () => import('./views/Login.vue')},{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue')} \]

因為項目中需要用到樣式什么的,這里我引入了iView,main.js代碼:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css'; Vue.use(iView)Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App) }).$mount('#app')

因為項目中要用到加載數據的動畫,所以需要在store.js中的state中配置:

state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;} },

在App.vue中配置跳轉:

<template><div><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template>

Home.vue代碼:

<template><div><h1>首頁面</h1></div> </template>

Login.vue代碼:

<template><div><i-input placeholder="請輸入用戶名..."></i-input><i-button type="primary">登錄</i-button></div> </template>

Profile.vue代碼:

<template> <div><h1>個人中心</h1> </div> </template>

然后在libs文件夾下面新建一個ajaxRequest.js文件,用來封裝我們自己的 axios 和 加載動畫 等

搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

import axios from 'axios' import store from '../store'//當第一次請求時,顯示loading class AjaxRequest {//當new的時候,調用這個方法constructor() {//請求的基礎路徑this.baseURL = process.env.NODE\_ENV == "production" ? "/" : "http://localhost:3000"this.timeout = 3000 //超時時間this.queue = {} //存放每一次的請求}//定義一個方法,把options展開merge(options) {return {...options,baseURL: this.baseURL,timeout: this.timeout}}//封裝一個攔截方法setInterceptor(instance, url) {//請求攔截,每次請求時,都要加上一個loading效果instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = 'xxx'//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config})//響應攔截instance.interceptors.response.use((res) => {//刪除queue里面的鏈接,如果同一個按鈕,你一秒之內點擊無數次,但是他只處理第一次操作delete this.queue\[url\]//隱藏loading動畫if (Object.keys(this.queue).length === 0) {store.commit('hideLoading')}//返回的結果return res.data})}request(options) {let instance = axios.create() //創建一個axios實例this.setInterceptor(instance, options.url) //設置攔截let config = this.merge(options)return instance(config) //axios執行后,返回promise} }export default new AjaxRequest;

然后在api文件夾下新建一個user.js文件用來放用戶相關的調用接口的方法(當你想要調用接口的時候,直接調用里面的方法就好):

import axios from '../libs/ajaxRequset'// 用戶相關的接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }

修改Home.vue中的代碼:

<template><div><h1>首頁面</h1><p>當前登錄的用戶名是{{$store.state.username}}</p></div> </template><script> //如果用export導出的話,要用這種形式,相當于解構賦值 import {getUser} from '../api/user' export default {name:'home',async mounted(){let r = await getUser()console.log(r);} } </script>

修改App.vue中的代碼(加動畫效果):

<template><div><Spin size="large" fix v-if="$store.state.isShowLoading">加載中...</Spin><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template><style> #app {font-family: "Avenir", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50; } #nav {padding: 30px; }#nav a {font-weight: bold;color: #2c3e50; }#nav a.router-link-exact-active {color: #42b983; } </style>

運行效果:

使用 JWT

在server.js中新增代碼,使用 JWT,并寫好登錄和驗證的接口:

let jwt = require('jsonwebtoken')let secret = "xwc"//登錄的接口 app.post('/login',(req,res)=>{let {username} = req.body;if(username === 'Fan'){//登錄成功后返回一個tokenres.json({code:0,username:'Fan',token:jwt.sign({username:'Fan'},secret,{expiresIn:20 //表示token20秒過期})})}else{//登錄失敗res.json({code:1,data:'登錄失敗了'})} })//驗證token的接口 app.get('/validate',(req,res)=>{let token = req.headers.authorization; //我們會把token放到我們自己設置的http的頭authorization中,在這里可以直接拿到jwt.verify(token,secret,(err,decode)=>{ //驗證tokenif(err){return res.json({code:1,data:'token失效了'})}else{// token合法 在這里,需要把token的時效延長,//總不能我們看著看著突然讓我們重新登錄,token過期的意思是,你在這之間不進行任何操作才會過期res.json({code:0,username:decode.username,token:jwt.sign({username:'Fan'},secret,{ //合法時,我們需要重新生成一個token,我們每次切換路由,都要重新生成一個tokenexpiresIn:20})})}}) })

接著在api文件夾下的user.js文件中添加登錄和驗證的方法:

import axios from '../libs/ajaxRequest'// 用戶相關的接口// 調獲取用戶信息的接口 向外暴露一個getUser方法 這個方法中調了接口 // 在組件中,就可以使用getUser,就相當于調用接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }// 再向外暴露一個登錄的方法,方法內部也是調接口 // 在登錄組件中就可以調用Login方法,需要給方法傳遞一個用戶名 export const login = (username)=>{return axios.request({url:'/login',method:'post',data:{username}}) }//驗證token方法 export const validate = ()=>{return axios.request({url:'/validate',method:'get'}) }

接著我們在lib文件夾下新建一個local.js文件,用來設置或者獲取localStorage里的token:

//把獲得到的token存到localStorage里 export const setLocal = (key,value)=>{if(typeof value == 'object'){ //如果傳過來的是對象,則轉換成字符串value = JSON.stringify(value)}localStorage.setItem(key,value) //存到localStorage里 }//獲取localStorage里的token export const getLocal = (key)=>{return localStorage.getItem(key) }

然后修改store.js中的代碼:

import Vue from 'vue' import Vuex from 'vuex' import {login,validate} from './api/user' //必須用這種方式引入 import {setLocal} from './libs/local' //引入lib文件夾下的local.js文件中的setLocal方法(往localStorage里存放token)Vue.use(Vuex)export default new Vuex.Store({state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;},//定義修改用戶名的方法setUser(state,username){state.username = username}},// actions存放接口的調用 dispatch actions里面放方法actions: {//這里面所有的方法都是異步的//登錄方法async toLogin({commit},username){let r = await login(username) //調用user.js中的login方法,也就是調用登錄接口// console.log(r);if(r.code === 0){ //登錄成功后會給你返回json數據,里面有code//登錄成功了commit('setUser',r.username) //修改用戶名setLocal('token',r.token) //把得到的token存到localStorage里}else{// console.log('............');return Promise.reject(r.data); //如果失敗,返回一個promise失敗態}},//驗證token方法async validate({commit}){let r = await validate(); //調用user.js中的validate方法,也就是調用驗證接口if(r.code === 0){commit('setUser',r.username)setLocal('token',r.token) //我們說了,驗證通過,或者每次切換路由時,都要重新生成token}return r.code === 0; //返回token是否失效,true或者false}} })

修改Login.vue中的代碼:

<template><div><i-input v-model="username" placeholder="請輸入用戶名..."></i-input><i-button type="primary" @click="login()">登錄</i-button></div> </template><script> import {mapActions} from 'vuex' //使用vuex中的mapActions方法,不會的請參考我的文章vuex的使用方法 export default {data(){return{username:'' //定義一個用戶名}},methods:{...mapActions(\['toLogin'\]), //獲取store.js文件中的actions中的toLogin方法login(){// console.log(this\['toLogin'\](this.username));//使用獲取到的toLogin方法this\['toLogin'\](this.username).then(data=>{ //因為toLogin返回的是一個Promise,所以可以.thenthis.$router.push('/') //登錄成功,跳到首頁面},err=>{this.$Message.error(err)})}} } </script>

別忘了修改ajaxRequest.js文件,在請求攔截的時候,需要加個頭,前面我們寫死了,這里,要把 token 給他,然后每次路由跳轉訪問頁面的時候,都會帶上這個頭,用來驗證:

import {getLocal} from "../libs/local" //引入//請求攔截,每次請求時,都要加上一個loading效果 instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = getLocal('token')//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config })

接著在router.js中設置路由:
哪個頁面需要登錄后才能訪問的話,給這個路由添加meta,假如我的 個人中心頁面 需要登錄后才能訪問,那么我需要修改代碼:

{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue'),meta:{needLogin:true} }

最后修改main.js中的代碼,當切換路由時,進行驗證:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css';Vue.use(iView)Vue.config.productionTip = false//每一次切換路由時,都執行這個導航守衛 router.beforeEach(async (to,from,next)=>{let isLogin = await store.dispatch('validate') //判斷是否登錄了// needLogin 表示哪些路由需要在登錄條件下才能訪問console.log(to);let needLogin = to.matched.some(match=>match.meta.needLogin)if(needLogin){//需要登錄if(isLogin){//登錄過了next()}else{//沒有登錄next('/login')}}else{//不需要登錄if(isLogin && to.path === '/login'){ //如果你訪問login頁面,則給你跳到首頁面,因為不需要登錄next('/')}else{next()}} })new Vue({router,store,render: h => h(App) }).$mount('#app')

有關需要注意的點,都加注釋了,好好看注釋就行

至此,整個案例就結束了

?

挺詳細的一個案例項目,值得參考!


作者:YXi

https://juejin.im/post/6844903959883218951)

幾乎在所有的項目中都離不開攔截器登錄驗證,這是必需的。如果你學會了這個 demo,那么幾乎所有網站的登錄驗證,加載動畫就都會了,所以背也要背會

所以本章以一個 demo 為例,來幫助大家理解攔截器登錄驗證控制

文章后面有源碼,可以下載下來運行一下

先來看看效果:

功能:

  • 當你訪問首頁的時候,會有一個加載動畫,就是攔截器的功勞,并且首頁會有一個當前登錄的用戶名,默認是 wangcai,等你登錄成功后,會替換成你自己登錄的用戶名

  • 當你沒有登錄的時候,可以訪問首頁和登錄頁,但是訪問不了個人中心 (Profile),當你訪問個人中心,會給你自動跳轉到登錄頁

  • 當你在登錄頁進行登錄,如果用戶名輸入錯誤的話,會彈出錯誤信息

  • 當你輸入正確的時候 (我設置了 Fan 為正確的用戶名),點擊登錄,登錄成功后,會自動給你跳轉到首頁

  • 并且登錄成功后,如果你再點擊想進入登錄頁,是不行的,他會自動給你跳轉到首頁

  • 登錄成功后,就可以訪問 個人中心頁面

  • 如果你超過 20 秒 不對頁面進行操作 (我設置的是 20 秒,可以自行設置),那么 token 會自動失效,那么你就訪問不了個人中心,你需要再次登錄

  • 如果你在 20 秒 之內,操作頁面的話,那么 token 的值是不會失效的,所以是不需要再次登錄的。也就是說,在 20 秒 之內,你每次進行路由跳轉的時候,token 的值和時間就會自動重置,防止失效讓你再次登錄(總不能讓你看著看著突然讓你登錄)

  • 搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

下面就讓我們開始吧!!!(有關代碼的解釋說明已在代碼中注釋

案例

使用攔截器并封裝axios

新建一個 Vue 項目 (vue create demo)

刪去不必要的文件和代碼,經典化代碼

安裝需要的依賴:

package.json文件部分代碼:

"dependencies": {"axios": "^0.19.0","body-parser": "^1.19.0","core-js": "^2.6.5","express": "^4.17.1","iview": "^4.0.0-rc.4","jsonwebtoken": "^8.5.1","vue": "^2.6.10","vue-router": "^3.0.3","vuex": "^3.0.1" },

在server.js文件中配置跨域,并書寫測試接口:

let express = require('express') let bodyParser = require('body-parser')let app = express()// 配置跨域 app.use((req, res, next) => {res.header("Access-Control-Allow-Origin", "\*");res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"),res.header("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization")if (req.method.toLowerCase() === "options") {return res.end();}next(); })// 配置bodyparser app.use(bodyParser.json())app.get("/user", (req, res) => {//在請求數據時,要加一個動畫,為了測試,所以讓它時間長點,加了一個定時器setTimeout(() => {res.json({name: "wangcai"})}, 500) })app.listen(3000)

在router.js中配置路由:

routes: \[{path: '/',name: 'home',component: Home},{path: '/login',name: 'login',component: () => import('./views/Login.vue')},{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue')} \]

因為項目中需要用到樣式什么的,這里我引入了iView,main.js代碼:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css'; Vue.use(iView)Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App) }).$mount('#app')

因為項目中要用到加載數據的動畫,所以需要在store.js中的state中配置:

state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;} },

在App.vue中配置跳轉:

<template><div><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template>

Home.vue代碼:

<template><div><h1>首頁面</h1></div> </template>

Login.vue代碼:

<template><div><i-input placeholder="請輸入用戶名..."></i-input><i-button type="primary">登錄</i-button></div> </template>

Profile.vue代碼:

<template> <div><h1>個人中心</h1> </div> </template>

然后在libs文件夾下面新建一個ajaxRequest.js文件,用來封裝我們自己的 axios 和 加載動畫 等

搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!

import axios from 'axios' import store from '../store'//當第一次請求時,顯示loading class AjaxRequest {//當new的時候,調用這個方法constructor() {//請求的基礎路徑this.baseURL = process.env.NODE\_ENV == "production" ? "/" : "http://localhost:3000"this.timeout = 3000 //超時時間this.queue = {} //存放每一次的請求}//定義一個方法,把options展開merge(options) {return {...options,baseURL: this.baseURL,timeout: this.timeout}}//封裝一個攔截方法setInterceptor(instance, url) {//請求攔截,每次請求時,都要加上一個loading效果instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = 'xxx'//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config})//響應攔截instance.interceptors.response.use((res) => {//刪除queue里面的鏈接,如果同一個按鈕,你一秒之內點擊無數次,但是他只處理第一次操作delete this.queue\[url\]//隱藏loading動畫if (Object.keys(this.queue).length === 0) {store.commit('hideLoading')}//返回的結果return res.data})}request(options) {let instance = axios.create() //創建一個axios實例this.setInterceptor(instance, options.url) //設置攔截let config = this.merge(options)return instance(config) //axios執行后,返回promise} }export default new AjaxRequest;

然后在api文件夾下新建一個user.js文件用來放用戶相關的調用接口的方法(當你想要調用接口的時候,直接調用里面的方法就好):

import axios from '../libs/ajaxRequset'// 用戶相關的接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }

修改Home.vue中的代碼:

<template><div><h1>首頁面</h1><p>當前登錄的用戶名是{{$store.state.username}}</p></div> </template><script> //如果用export導出的話,要用這種形式,相當于解構賦值 import {getUser} from '../api/user' export default {name:'home',async mounted(){let r = await getUser()console.log(r);} } </script>

修改App.vue中的代碼(加動畫效果):

<template><div><Spin size="large" fix v-if="$store.state.isShowLoading">加載中...</Spin><div><router-link to="/">Home</router-link> |<router-link to="/login">Login</router-link> |<router-link to="/profile">Profile</router-link></div><router-view/></div> </template><style> #app {font-family: "Avenir", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50; } #nav {padding: 30px; }#nav a {font-weight: bold;color: #2c3e50; }#nav a.router-link-exact-active {color: #42b983; } </style>

運行效果:

使用 JWT

在server.js中新增代碼,使用 JWT,并寫好登錄和驗證的接口:

let jwt = require('jsonwebtoken')let secret = "xwc"//登錄的接口 app.post('/login',(req,res)=>{let {username} = req.body;if(username === 'Fan'){//登錄成功后返回一個tokenres.json({code:0,username:'Fan',token:jwt.sign({username:'Fan'},secret,{expiresIn:20 //表示token20秒過期})})}else{//登錄失敗res.json({code:1,data:'登錄失敗了'})} })//驗證token的接口 app.get('/validate',(req,res)=>{let token = req.headers.authorization; //我們會把token放到我們自己設置的http的頭authorization中,在這里可以直接拿到jwt.verify(token,secret,(err,decode)=>{ //驗證tokenif(err){return res.json({code:1,data:'token失效了'})}else{// token合法 在這里,需要把token的時效延長,//總不能我們看著看著突然讓我們重新登錄,token過期的意思是,你在這之間不進行任何操作才會過期res.json({code:0,username:decode.username,token:jwt.sign({username:'Fan'},secret,{ //合法時,我們需要重新生成一個token,我們每次切換路由,都要重新生成一個tokenexpiresIn:20})})}}) })

接著在api文件夾下的user.js文件中添加登錄和驗證的方法:

import axios from '../libs/ajaxRequest'// 用戶相關的接口// 調獲取用戶信息的接口 向外暴露一個getUser方法 這個方法中調了接口 // 在組件中,就可以使用getUser,就相當于調用接口 export const getUser = ()=>{return axios.request({url:'/user',method:'get'}) }// 再向外暴露一個登錄的方法,方法內部也是調接口 // 在登錄組件中就可以調用Login方法,需要給方法傳遞一個用戶名 export const login = (username)=>{return axios.request({url:'/login',method:'post',data:{username}}) }//驗證token方法 export const validate = ()=>{return axios.request({url:'/validate',method:'get'}) }

接著我們在lib文件夾下新建一個local.js文件,用來設置或者獲取localStorage里的token:

//把獲得到的token存到localStorage里 export const setLocal = (key,value)=>{if(typeof value == 'object'){ //如果傳過來的是對象,則轉換成字符串value = JSON.stringify(value)}localStorage.setItem(key,value) //存到localStorage里 }//獲取localStorage里的token export const getLocal = (key)=>{return localStorage.getItem(key) }

然后修改store.js中的代碼:

import Vue from 'vue' import Vuex from 'vuex' import {login,validate} from './api/user' //必須用這種方式引入 import {setLocal} from './libs/local' //引入lib文件夾下的local.js文件中的setLocal方法(往localStorage里存放token)Vue.use(Vuex)export default new Vuex.Store({state: {//定義動畫是否顯示isShowLoading:false,username:'wangcai'},mutations: {//使動畫顯示showLoading(state){state.isShowLoading = true;},//使動畫隱藏hideLoading(state){state.isShowLoading = false;},//定義修改用戶名的方法setUser(state,username){state.username = username}},// actions存放接口的調用 dispatch actions里面放方法actions: {//這里面所有的方法都是異步的//登錄方法async toLogin({commit},username){let r = await login(username) //調用user.js中的login方法,也就是調用登錄接口// console.log(r);if(r.code === 0){ //登錄成功后會給你返回json數據,里面有code//登錄成功了commit('setUser',r.username) //修改用戶名setLocal('token',r.token) //把得到的token存到localStorage里}else{// console.log('............');return Promise.reject(r.data); //如果失敗,返回一個promise失敗態}},//驗證token方法async validate({commit}){let r = await validate(); //調用user.js中的validate方法,也就是調用驗證接口if(r.code === 0){commit('setUser',r.username)setLocal('token',r.token) //我們說了,驗證通過,或者每次切換路由時,都要重新生成token}return r.code === 0; //返回token是否失效,true或者false}} })

修改Login.vue中的代碼:

<template><div><i-input v-model="username" placeholder="請輸入用戶名..."></i-input><i-button type="primary" @click="login()">登錄</i-button></div> </template><script> import {mapActions} from 'vuex' //使用vuex中的mapActions方法,不會的請參考我的文章vuex的使用方法 export default {data(){return{username:'' //定義一個用戶名}},methods:{...mapActions(\['toLogin'\]), //獲取store.js文件中的actions中的toLogin方法login(){// console.log(this\['toLogin'\](this.username));//使用獲取到的toLogin方法this\['toLogin'\](this.username).then(data=>{ //因為toLogin返回的是一個Promise,所以可以.thenthis.$router.push('/') //登錄成功,跳到首頁面},err=>{this.$Message.error(err)})}} } </script>

別忘了修改ajaxRequest.js文件,在請求攔截的時候,需要加個頭,前面我們寫死了,這里,要把 token 給他,然后每次路由跳轉訪問頁面的時候,都會帶上這個頭,用來驗證:

import {getLocal} from "../libs/local" //引入//請求攔截,每次請求時,都要加上一個loading效果 instance.interceptors.request.use((config) => {//每次請求時,都給他加一個Authorization頭,在JWT驗證時要用config.headers.Authorization = getLocal('token')//第一次請求時,顯示loading動畫if (Object.keys(this.queue).length === 0) {store.commit('showLoading')}this.queue\[url\] = url;return config })

接著在router.js中設置路由:
哪個頁面需要登錄后才能訪問的話,給這個路由添加meta,假如我的 個人中心頁面 需要登錄后才能訪問,那么我需要修改代碼:

{path: '/profile',name: 'profile',component: () => import('./views/Profile.vue'),meta:{needLogin:true} }

最后修改main.js中的代碼,當切換路由時,進行驗證:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'//引入iView import iView from 'iview' import 'iview/dist/styles/iview.css';Vue.use(iView)Vue.config.productionTip = false//每一次切換路由時,都執行這個導航守衛 router.beforeEach(async (to,from,next)=>{let isLogin = await store.dispatch('validate') //判斷是否登錄了// needLogin 表示哪些路由需要在登錄條件下才能訪問console.log(to);let needLogin = to.matched.some(match=>match.meta.needLogin)if(needLogin){//需要登錄if(isLogin){//登錄過了next()}else{//沒有登錄next('/login')}}else{//不需要登錄if(isLogin && to.path === '/login'){ //如果你訪問login頁面,則給你跳到首頁面,因為不需要登錄next('/')}else{next()}} })new Vue({router,store,render: h => h(App) }).$mount('#app')

有關需要注意的點,都加注釋了,好好看注釋就行

至此,整個案例就結束了

總結

以上是生活随笔為你收集整理的Vue项目使用拦截器和JWT验证 完整案例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本91网站 | 亚洲精品入口 | 亚洲成人网页 | 国产精品久久久久久久一区探花 | 丝袜一区二区三区四区 | 大尺度做爰床戏呻吟舒畅 | 国产无遮挡又黄又爽免费视频 | 国产午夜视频在线观看 | 亚洲清纯唯美 | 91久久精品一区二区别 | 熟妇大屁股一区二区三区视频 | 丰满少妇一区二区 | 日本亚洲色大成网站www久久 | 丁香花完整视频在线观看 | 九七伦理电影 | 1024精品一区二区三区日韩 | 中国超碰 | 69xx国产| 国产精品无码专区 | 琪琪色综合 | 午夜精品久久久久久久96蜜桃 | 色婷婷成人| 久久精品一区二区三区黑人印度 | 日韩免费观看一区二区三区 | 色婷婷a | 绝顶高潮合集videos | 水蜜桃影库 | jjzz日本女人 | 粉嫩av蜜桃av蜜臀av | 深夜的私人秘书 | 久久女人天堂 | 人人爽人人爽人人片av | 国产99久久精品 | 国产在线视频网站 | 美女视频黄色在线观看 | 一区二区三区视频免费看 | 欧美一区免费观看 | av在线二区| 一本色道久久综合亚洲二区三区 | 久久免费看片 | 日韩av网址大全 | 大尺度叫床戏做爰视频 | 欧美特级一级片 | 99久久精品国产一区二区成人 | 三级性生活视频 | 色婷婷色婷婷 | 总受合集lunjian双性h | www国产精品内射熟女 | 女人被男人操 | 韩国一区二区三区在线观看 | 国产精品一页 | 99re99| 黄色片18 | 午夜精品福利一区二区蜜股av | 一卡二卡在线 | 国产精品一区二区不卡 | 亚洲欧美日韩一区二区三区在线观看 | 日韩一级影视 | 欧洲精品久久久 | 亚洲网在线观看 | 欧美福利视频在线 | 操亚洲美女 | 欧美亚洲综合在线 | 精品国产一区一区二区三亚瑟 | a天堂视频 | 九色一区 | 国产一级美女 | 亚洲深爱| 午夜伦伦电影理论片费看 | 国产美女www爽爽爽视频 | 久久久国产精华液999999 | 大香伊人久久 | av在线首页 | 丰满孕妇性春猛交xx大陆 | 少妇一级淫片免费视频 | 性xx紧缚网站 | 欧美交换国产一区内射 | 在线亚洲精品 | 麻豆一区二区在线 | xxx视频网站| 久草福利网 | 亚洲伦理天堂 | 97香蕉久久超级碰碰高清版 | www.欧美激情 | a片在线免费观看 | 日韩成人在线免费视频 | 成人性生交大片免费看中文 | 毛片全黄 | 久久视频黄色 | 亚洲自拍第二页 | 校园春色综合 | 国产高清av| 天天做天天爱天天操 | 亚洲AV无码国产精品午夜字幕 | 在线观看亚洲欧美 | 污视频在线免费 | 亚洲av永久无码精品放毛片 | 麻豆国产精品一区 | 亚洲国产精品久久AV |