在前後端完全分離的情況下,Vue項目中實現token驗證大致思路如下:
1、第一次登錄的時候,前端調後端的登陸接口,發送用戶名和密碼
2、後端收到請求,驗證用戶名和密碼,驗證成功,就給前端返回一個token
3、前端拿到token,將token存儲到localStorage和vuex中,並跳轉路由頁面
4、前端每次跳轉路由,就判斷 localStroage 中有無 token ,沒有就跳轉到登錄頁面,有則跳轉到對應路由頁面
5、每次調後端接口,都要在請求頭中加token
6、後端判斷請求頭中有無token,有token,就拿到token並驗證token,驗證成功就返回數據,驗證失敗(例如:token過期)就返回401,請求頭中沒有token也返回401
7、如果前端拿到狀態碼爲401,就清除token信息並跳轉到登錄頁面
下面說說具體的操作:
一、在store的index.js中添加保存和刪除token的方法。
二、在login.vue中登入方法調用接口成功把token傳給localsortage。
三、在main.js中添加攔截器並且在請求頭中添加token。
1.mutation的方法中增加setSorage和removeStorage的方法,爲後面的獲取token放在localsortage做準備。
import Vue from 'vue'
import Vuex from 'vuex'
import {getproductByIndex} from '@/data/getdata.js'
Vue.use(Vuex)
const key ='token'
const store =new Vuex.Store({
state(){
return{
token:localStorage.getItem('token') ? localStorage.getItem('token'):''
}
},
getters:{
getSortage:function (state) {
if(!state.token){
state.token =JSON.parse(localStorage.getItem(key))
}
return state.token
}
},
mutations:{
$_setStorage(state,value){
state.token =value;
localStorage.setItem(key,JSON.stringify(value))
},
$_removeStorage(state){
state.token =null;
localStorage.removeItem(key)
}
},
})
export default store
2.login.vue中method方法
checkLogin(){
if(this.checkCode()==true){
let mymes ={
userId:this.user,
userPwd:this.psw,
}
gologin(mymes).then(res=>{
if(res.status==200){
if(res.data.result==4){
//token的值儲存到localsortage
this.$store.commit('$_setStorage',{token:res.data.data[0].token})
this.$router.push({path:'/index'})
}else{
this.$message.error(res.request.response.msg);
}
}
})
}
},
注:this.$store.commit('$_setStorage',{token:res.data.data[0].token}) 這裏的token是需要和store index.js中的state的token命名一致
3.main.js中添加攔截器
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import store from './store'
import 'element-ui/lib/theme-chalk/index.css'
import 'font-awesome/css/font-awesome.css'
/*引入axios插件*/
import axios from 'axios'
Vue.use(ElementUI);
Vue.config.productionTip = false;
Vue.prototype.$http = axios;
/* eslint-disable no-new */
router.beforeEach((to, from, next) => {
if(to.path === '/login'){
next();
}else{
let token =window.localStorage.token;
if(token ==='null' || token ==='' || token === undefined){
next('/login');
}else{
next();
}
}
})
//添加請求攔截器
axios.interceptors.request.use(
config =>{
if(store.state.token){
config.headers.common['token'] =store.state.token.token
}
return config;
},
error =>{
//對請求錯誤做什麼
return Promise.reject(error);
}
)
//http reponse攔截器
axios.interceptors.response.use(
response =>{
return response;
},
error=>{
if(error.response){
switch(error.response.status){
case 401:
localStorage.removeItem('token');
/* router.push('/views/login');*/
router.replace({
path: '/views/login',
query: {redirect: router.currentRoute.fullPath}//登錄成功後跳入瀏覽的當前頁面
})
}
}
}
)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
4.查看token是否添加成功,這邊是需要調用一個接口的