借助axios的攔截器實(shí)現(xiàn)Vue.js中登陸狀態(tài)校驗(yàn)

axios介紹

什么是axios

axios是一個基于Promise的HTTP庫划纽,可以用在瀏覽器或node.js中。

axios特點(diǎn):

  1. 從瀏覽器中創(chuàng)建XMLHTTPRequest
  2. 從node.js端創(chuàng)建http請求
  3. 支持PromiseAPI
  4. 攔截請求和響應(yīng)
  5. 轉(zhuǎn)換請求數(shù)據(jù)和響應(yīng)數(shù)據(jù)
  6. 取消請求
  7. 自動轉(zhuǎn)換JSON數(shù)據(jù)
  8. 客戶端支持防御XSRF

axios攔截器

為什么使用攔截器

頁面發(fā)送http請求疼约,很多情況我們要對請求和其響應(yīng)進(jìn)行特定的處理;例如每個請求都附帶后端返回的token,拿到response之前l(fā)oading動畫的展示等速妖。如果請求數(shù)非常多虱颗,這樣處理起來會非常的麻煩沥匈,程序的優(yōu)雅性也會大打折扣。在這種情況下忘渔,axios為開發(fā)者提供了這樣一個API:攔截器高帖。攔截器分為 請求(request)攔截器和 響應(yīng)(response)攔截器。

  1. 在請求和響應(yīng)被then或catch處理前攔截它們畦粮。
//添加請求攔截器
axios.interceptors.request.use(function(config){
  //在請求發(fā)送之前做些什么
  return config
},function(error){
  //對請求錯誤做些什么
  return Promise.reject(error)
})
//添加響應(yīng)請求
axios.interceptors.reponse.use(function(reponse){
  //對響應(yīng)數(shù)據(jù)做些什么
  return reponse
},function(error){
  //對響應(yīng)錯誤做些什么
  return Promise.reject(error)
})
  1. 添加攔截器使用use
  2. 移除攔截器使用eject
var myInterceptors = axios.interceptors.request.use()
//移除攔截器
axios.interceptors.request.eject(myInterceptors)
  1. axios自定義實(shí)例添加攔截器
//自定義實(shí)例
var instance = axios.create()
//添加攔截器
instance.interceptors.request.use()

axios取消請求

  1. 使用cancel token取消請求
  2. 可以使用 CancelToken.source 工廠方法創(chuàng)建 cancel token散址,
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 處理錯誤
  }
});

// 取消請求(message 參數(shù)是可選的)
source.cancel('Operation canceled by the user.');
  1. 還可以通過傳遞一個 executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建 cancel token:
var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數(shù)接收一個 cancel 函數(shù)作為參數(shù)
    cancel = c;
  })
});

// 取消請求
cancel();

借助axios的攔截器實(shí)現(xiàn)Vue.js中登陸狀態(tài)校驗(yàn)

后臺系統(tǒng)中乖阵,不是每個頁面都需要登錄權(quán)限,所以要對需要進(jìn)行登錄權(quán)限的頁面做好標(biāo)記预麸,使用路由的meta標(biāo)簽

{
  path: '/userInfo',
  name: '/userInfo',
  meta: {
    requireAuth: true // 該路由需要登錄權(quán)限校驗(yàn)
  },
  component: userInfo
},{
  path: '/userInfo',
  name: '/userInfo',
  // 該路由需要登錄權(quán)限校驗(yàn)
  component: userInfo
}

定義一起全局前置守衛(wèi)瞪浸,每次跳轉(zhuǎn)路由,進(jìn)行權(quán)限校驗(yàn)

router.beforeEach((to,from,next) => {
  if(to.meta.requireAuth){ //如果路由需要校驗(yàn)權(quán)限
  /*
    從vuex拿出token碼吏祸,說明已經(jīng)登錄
    (前端的Token可以偽造,并不靠譜)
  */
    if(store.state.token){
      next() //正常跳轉(zhuǎn)頁面
    }else{
      next({
        path: "/login",
        query: {redirect: to.fullPath}
        /*將跳轉(zhuǎn)的路由地址作為參數(shù)帶給登錄頁对蒲,登錄成功后跳轉(zhuǎn)回改頁面 */
      })
    }
  }else {
    //如果不要校驗(yàn),直接進(jìn)入登錄頁
    next()
  }
})

但以上的實(shí)現(xiàn)存在問題贡翘,token可以偽造蹈矮,這是其一,其二鸣驱,token前端存在泛鸟,但后端可能已經(jīng)失效。所以采用后端的一層校驗(yàn)丐巫,確保權(quán)限token的準(zhǔn)確性谈况。就要使用到axios中的攔截器(interceptors)。

實(shí)現(xiàn)思路:如果前端有token 递胧,每次發(fā)送請求的時候碑韵,把token 發(fā)送給后端,后端按到token后缎脾,進(jì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)攔截:后端拿到Token,發(fā)現(xiàn)token ,返回401(前后端約定好的),此時前端就知道作何處理

// response interceptor
axios.interceptors.response.use(
    response => {
        // 如果返回的狀態(tài)碼為200遗菠,說明接口請求成功联喘,可以正常拿到數(shù)據(jù)
        // 否則的話拋出錯誤
        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
            return Promise.reject(response);
        }
    },
    // 服務(wù)器狀態(tài)碼不是2開頭的的情況
    // 這里可以跟你們的后臺開發(fā)人員協(xié)商好統(tǒng)一的錯誤狀態(tài)碼
    // 然后根據(jù)返回的狀態(tài)碼進(jìn)行一些操作,例如登錄過期提示辙纬,錯誤提示等等
    // 下面列舉幾個常見的操作豁遭,其他需求可自行擴(kuò)展
    error => {
        if (error.response.status) {
            switch (error.response.status) {
                // 401: 未登錄
                // 未登錄則跳轉(zhuǎn)登錄頁面,并攜帶當(dāng)前頁面的路徑
                // 在登錄成功后返回當(dāng)前頁面贺拣,這一步需要在登錄頁操作蓖谢。
                case 401:
                    router.replace({
                        path: '/login',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                    break;

                // 403 token過期
                // 登錄過期對用戶進(jìn)行提示
                // 清除本地token和清空vuex中token對象
                // 跳轉(zhuǎn)登錄頁面
                case 403:
                      Message({
                        message: '登錄過期,請重新登錄',
                        duration: 1000,
                        forbidClick: true
                    });
                    // 清除token
                    localStorage.removeItem('token');
                    store.commit('loginSuccess', null);
                    // 跳轉(zhuǎn)登錄頁面譬涡,并將要瀏覽的頁面fullPath傳過去闪幽,登錄成功后跳轉(zhuǎn)需要訪問的頁面
                    setTimeout(() => {
                        router.replace({
                            path: '/login',
                            query: {
                                redirect: router.currentRoute.fullPath
                            }
                        });
                    }, 1000);
                    break;

                // 404請求不存在
                case 404:
                    Message({
                        message: '網(wǎng)絡(luò)請求不存在',
                        duration: 1500,
                        forbidClick: true
                    });
                    break;
                // 其他錯誤,直接拋出錯誤提示
                default:
                    Message({
                        message: error.response.data.message,
                        duration: 1500,
                        forbidClick: true
                    });
            }
            return Promise.reject(error.response);
        }
    }
});

對于token

token涡匀,一般是在登錄完成之后盯腌,將用戶的token通過localStorage或者cookie存在本地,然后用戶每次在進(jìn)入頁面的時候陨瘩,會首先從本地存儲中讀取token腕够,如果token存在說明用戶已經(jīng)登陸過级乍,則更新vuex中的token狀態(tài)。然后燕少,在每次請求接口的時候卡者,都會在請求的header中攜帶token,服務(wù)器就可以根據(jù)你攜帶的token來判斷你的登錄是否過期客们,如果沒有攜帶崇决,則說明沒有登錄過。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末底挫,一起剝皮案震驚了整個濱河市恒傻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌建邓,老刑警劉巖盈厘,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異官边,居然都是意外死亡沸手,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門注簿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來契吉,“玉大人,你說我怎么就攤上這事诡渴【杈В” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵妄辩,是天一觀的道長惑灵。 經(jīng)常有香客問我,道長眼耀,這世上最難降的妖魔是什么英支? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮哮伟,結(jié)果婚禮上潭辈,老公的妹妹穿的比我還像新娘。我一直安慰自己澈吨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布寄摆。 她就那樣靜靜地躺著谅辣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婶恼。 梳的紋絲不亂的頭發(fā)上桑阶,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天柏副,我揣著相機(jī)與錄音,去河邊找鬼蚣录。 笑死割择,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的萎河。 我是一名探鬼主播荔泳,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虐杯!你這毒婦竟也來了玛歌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤擎椰,失蹤者是張志新(化名)和其女友劉穎支子,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體达舒,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡值朋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了巩搏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昨登。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖塔猾,靈堂內(nèi)的尸體忽然破棺而出篙骡,到底是詐尸還是另有隱情,我是刑警寧澤丈甸,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布糯俗,位于F島的核電站,受9級特大地震影響睦擂,放射性物質(zhì)發(fā)生泄漏得湘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一顿仇、第九天 我趴在偏房一處隱蔽的房頂上張望淘正。 院中可真熱鬧,春花似錦臼闻、人聲如沸鸿吆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惩淳。三九已至,卻和暖如春乓搬,著一層夾襖步出監(jiān)牢的瞬間思犁,已是汗流浹背代虾。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留激蹲,地道東北人棉磨。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像学辱,于是被迫代替她去往敵國和親乘瓤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344