在做Vue中的登陸校驗(yàn)時(shí)亮钦,思路應(yīng)該是這樣的:先確定一個(gè)路由頁面是否需要登陸才能訪問馆截,如果需要,就需要用戶登陸,如果不需要蜡娶,用戶直接可以訪問混卵。
那么,首先來說窖张,后臺(tái)系統(tǒng)中幕随,不一定每一個(gè)頁面都要進(jìn)行登陸權(quán)限,所以我們要通過路由的meta標(biāo)簽對需要做校驗(yàn)的路由頁面做好標(biāo)記荤堪,在配置路由時(shí)合陵,我們可以在meta屬性中,加入是否需要登陸的字段澄阳,如果requireAuth是true,就說明這條路由需要登陸才能訪問:
{
path: '/userInfo',
name: 'userInfo',
meta: {
requireAuth: true, // 該路由項(xiàng)需要權(quán)限校驗(yàn)
}
component: userInfo
}, {
path: '/userList',
name: 'userList', // 該路由項(xiàng)不需要權(quán)限校驗(yàn)
component: userInfo
}
之后踏拜,我們可以定義一個(gè)路由守衛(wèi)碎赢,每次路由跳轉(zhuǎn),我們都來做一次權(quán)限校驗(yàn)速梗,參考如下代碼
router.beforeEach((to, from, next) => {
if(to.meta.requireAuth) { // 如果路由項(xiàng)需要權(quán)限校驗(yàn)
/*
從Vuex拿出token碼肮塞,說明已登陸
(前端的token可偽造,所以這并不是完全靠譜姻锁,后面繼續(xù)說)
*/
if (store.state.token) {
next() // 正常跳轉(zhuǎn)頁面
} else {
next({
path: '/login',
query: {redirect: to.fullPath}
/* 將跳轉(zhuǎn)的路由地址作為參數(shù)帶給登陸頁枕赵,登錄成功后跳轉(zhuǎn)回該頁面 */
})
}
} else { // 如果不需要權(quán)限校驗(yàn),直接進(jìn)入路由頁面
next();
}
})
如果用戶的Vuex中登陸狀態(tài)(token)存在位隶,就說明登陸了拷窜,如果沒有值,就跳轉(zhuǎn)去登陸頁面涧黄。用戶在登陸頁面登陸后篮昧,要在Vuex中保存登陸狀態(tài)(token)。(實(shí)際上如果做持久存儲(chǔ)笋妥,還應(yīng)該把登陸狀態(tài)存在localStorage或者cookie中)
然而懊昨,單純這么來做并不靠譜,首先春宣,token可以用戶自己偽造酵颁,其次,有可能token在前端存在月帝,但是由于登陸時(shí)間過長躏惋, 已經(jīng)超出登陸最長時(shí)效期,這時(shí)嫁赏,后端中其掂,這個(gè)token已經(jīng)失效。
所以潦蝇,這么做權(quán)限校驗(yàn)并不準(zhǔn)確款熬,那么接下來深寥,我們可以在發(fā)請求的時(shí)候,通過后端的一層校驗(yàn)贤牛,進(jìn)一步確保權(quán)限狀態(tài)的準(zhǔn)確性惋鹅。
這一步,要用到axios里面的攔截器殉簸,所以以下代碼建立在項(xiàng)目使用axios的基礎(chǔ)上闰集。axios的攔截器(Interceptors),默認(rèn)配置(axios.defaults)還有 axios.create() 創(chuàng)建出的實(shí)例實(shí)際上在封裝請求時(shí)非常有用般卑,如果你沒接觸過武鲁,趕緊到官方文檔看一下!
我們先來看蝠检,在每次請求時(shí)沐鼠,我們進(jìn)行如下的攔截,這么做的意思是叹谁,如果前端有token饲梭,我每次都把token給后端,后端拿到這個(gè)token后會(huì)到后端再進(jìn)行一次權(quán)限校驗(yàn)焰檩,然后把校驗(yàn)結(jié)果在接口中反饋:
axios.interceptors.request.use( requestConfig => {
if (store.state.token) {
config.headers.Authorization = `${store.state.token}`;
}
return requestConfig;
}, err => {
return Promise.reject(err);
});
然后我們再來看憔涉,對應(yīng)一定要再寫一個(gè)response攔截器,處理響應(yīng)數(shù)據(jù)析苫。如果后端拿到前端的token兜叨,發(fā)現(xiàn)token失效,我們要求后端接口返回401的返回碼藤违,這樣浪腐,前端就可以這么處理了:
axios.interceptors.response.use( response => {
return response;
}, error => {
if (error.response) {
switch (error.response.status) {
case 401:
/*
返回 401 表示前端的token已失效
當(dāng)然,你也可以和后端也定其他的方式來表示token失效
需要前端清除Vuex中的token顿乒,頁面跳轉(zhuǎn)到登陸頁
*/
store.commit(types.LOGOUT);
router.replace({
path: 'login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
}
return Promise.reject(error.response.data) //返回接口返回的錯(cuò)誤信息
});
借助axios的攔截器议街,我們不但前端做了登陸校驗(yàn),而且每次請求后端接口的時(shí)候璧榄,都會(huì)攜帶數(shù)據(jù)讓后端再次做登陸校驗(yàn)特漩,這樣的一個(gè)登陸校驗(yàn)流程就很標(biāo)準(zhǔn)了。
這篇文章寫的稍微有些寬骨杂,大家看到哪里不太明白隨時(shí)提問涂身,我再展開來講。
作者:DellLee
鏈接:https://www.imooc.com/article/25167?block_id=tuijian_wz
來源:慕課網(wǎng)
2搓蚪、第二篇有關(guān)vue中axios的文章
https://segmentfault.com/a/1190000016787376
在Vue中如何使用axios請求攔截
為什么要使用請求攔截蛤售?
如果不使用請求攔截,那么對每一條請求每一個(gè)狀態(tài)都要特殊處理,如果請求特殊狀態(tài)有數(shù)十個(gè)悴能,每個(gè)頁面有很多請求揣钦,那么頁面會(huì)變得很長很臃腫,不好維護(hù)漠酿。
下面是一個(gè)沒有請求攔截的例子:
//雙向數(shù)據(jù)綁定獲取值
let httpRequest = {};
httpRequest.loginName = this.loginName
httpRequest.password= this.password
this.$axios.post("/api/request", this.$qs.stringify(httpRequest)).then(data => {
//特殊錯(cuò)誤處理冯凹,狀態(tài)為10時(shí)為登錄超時(shí)
if(data.data.code === 10){
this.$Message.error("登錄已超時(shí),請重新登錄")
this.$router.push("/login")
//其余錯(cuò)誤狀態(tài)處理
}else if(data.data.code != 0){
this.$Message.error(data.data.msg)
//請求成功
}else if(data.data.code === 0){
//進(jìn)行成功業(yè)務(wù)邏輯
}
//.......
});
main.js
//請求發(fā)送攔截炒嘲,把數(shù)據(jù)發(fā)送給后臺(tái)之前做些什么......
axios.interceptors.request.use((request) => {
//這個(gè)例子中data是loginName和password
let REQUEST_DATA = request.data
//統(tǒng)一進(jìn)行qs模塊轉(zhuǎn)換
request.data = qs.stringify(REQUEST_DATA)
//再發(fā)送給后臺(tái)
return request;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
//請求返回?cái)r截宇姚,把數(shù)據(jù)返回到頁面之前做些什么...
axios.interceptors.response.use((response) => {
//特殊錯(cuò)誤處理,狀態(tài)為10時(shí)為登錄超時(shí)
if (response.data.code === 10) {
iView.Message.error("登錄已超時(shí)夫凸,請重新登錄");
router.push("/login")
//其余錯(cuò)誤狀態(tài)處理
} else if (response.data.code != 0) {
iView.Message.error(response.data.msg)
//請求成功
} else if(response.data.code === 0){
//將我們請求到的信息返回頁面中請求的邏輯
return response;
}
//......
}, function (error) {
return Promise.reject(error);
});
.vue
//雙向數(shù)據(jù)綁定獲取值
let httpRequest = {};
httpRequest.loginName = this.loginName
httpRequest.password= this.password
this.$axios.post("/api/request", httpRequest).then(data => {
//這是要先判斷data浑劳,如果請求的數(shù)據(jù)狀態(tài)code不為0,會(huì)被攔截,則data為undefined
if(data){
//進(jìn)行請求返回成功邏輯
}
});