1. 程式人生 > >token驗證機制

token驗證機制

最近在vue-cli專案實現登入的過程中用到了token驗證,在此總結如下


1. 登入時,客戶端通過使用者名稱與密碼請求登入
2. 服務端收到請求去驗證使用者名稱與密碼
3. 驗證通過,服務端會簽發一個Token,再把這個Token以響應發給客戶端.
4. 客戶端收到Token,儲存到本地,如Cookie,SessionStorage,LocalStorage.我們是存在cookie
5. 客戶端每次像伺服器請求API介面時候,都要帶上Token.
6. 客戶端每次跳轉路由的時候也要驗證Token登入態
7. 服務端收到請求,驗證Token,如果通過就返回資料,否則提示報錯資訊.

第一步:通過使用者名稱+密碼獲取token,存cookie


axios.post(this.Service.SERVER.login, {
    username: this.ruleForm.username,
    password: this.ruleForm.password
})
.then((res) => {
    if(res.token) {
        this.xes.setCookies('token', res.token, 2)
        this.$router.push({name: 'approveOnline'})
    }
})

第二步:路由跳轉進行登入態校驗

首先先比較一下下面兩段程式碼


router.beforeEach((to, from, next) => {
    let isLogin = xes.getCookies('token')
    if(!isLogin) {
         // 如果是登入頁面路徑,就直接跳下一步
         next('/login');
    }else{
         next()
    }
})

router.beforeEach((to, from, next) => {
    let isLogin = xes.getCookies('token')
    if(!isLogin) {
        // 如果是登入頁面路徑,就直接跳下一步
        if(to.path=='/login'){
            next();
        }else {
            next('/login');
        }
    }else{
      next()
    }
})

結果:第一段程式碼在頁面進行路由跳轉的時候會陷入死迴圈
原因:next後面帶路徑跳轉時會重新呼叫router.beforeEach,next後不加引數跳轉時不會執行beforeEach

第三步:axios請求攔截器配置token,校驗請求時的登入態


axios.interceptors.request.use((config) => {
    // 以防cookie失效,所以每次發請求都重新獲取token
    if(xes.getCookies('token')) {
        config.headers.common['Authorization'] = 'Token ' + xes.getCookies('token');
    }
    return config
}, (error) => {
    Message.error({
        message: '載入超時'
    })
    return Promise.reject(error)
})

此處遇到的坑:
axios請求頭部token的設定——因為axios.defaults.headers設定只在頁面初始化的時候獲取一次,會導致在頁面發起請求的時候不會重新去獲取登陸態,這樣就出現個問題,不論是否處於登陸態,已登陸的狀態會一直存在,為了避免這個問題,就需要在請求內部去設定獲取token,於是把攜帶token的頭部設定放在axios的請求攔截器裡,每次請求都重新獲取以便拿到最新的登陸態,這裡有個坑就是在請求攔截器裡設定頭部要用自定義設定,而不能用axios.defaults.headers預設設定,因為預設設定是優先於請求攔截器執行的,假如用了預設設定,其實設定的是下一次請求的請求頭而非本次請求(token是在axios.defaults.headers中攜帶的)

第四步:axios響應攔截器更新cookie


axios.interceptors.response.use((res) => {
    var _url = res.config.url.replace(axios.defaults.baseURL, '')
    if (res.data.stat == 1) {
        xes.setCookies('token', xes.getCookies('token'), 2)
    }
    return res.data
}

這樣做是考慮到使用者體驗,防止使用者在使用系統過程中由於cookie到期而中斷退出系統

總結

因為本次開發後端只是根據前端調介面時是否傳token來判斷是否登入,並未進行登入校驗,所以考慮的點比較多。考慮不周請指正

原文地址:https://segmentfault.com/a/1190000016814541