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

歡迎訪問 生活随笔!

生活随笔

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

vue

vue的token刷新处理

發布時間:2023/12/10 vue 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue的token刷新处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

以token處理登錄的web系統,一般會有兩個token:access-token和refresh-token。

node.js中,一般用jsonwebtoken這個模塊。

access-token,是用戶輸入登錄的賬號密碼,后臺去db驗證然后頒發的,它一般記錄在瀏覽器的cookie中,并在瀏覽器關閉時自動刪除,頁面訪問或ajax訪問會自動通過cookie傳回到后臺,后臺直接內存中校驗,不用訪問db,所以效率高;為了在access-token泄漏后及時止損,一般access-token會設置一個有效期,如1-8小時。

access-token設置了有效期后,過期了怎么辦?為了及時止損,有效期不能設置太長,過期是一定會遇到的,比如工作狂,如果有效期設置的是8小時,他開著瀏覽器工作12小時,費力斷斷續續花了1個小時(電話多,喝咖啡尿多)打了張訂單,提交時token過期了。再比如某些大屏幕展示的頁面,可能連續幾天幾月的開著。遇到過期怎么辦?

  • 重定向到登錄頁面,用戶輸入賬號密碼登錄后,再自動跳回訂單頁面,之前的資料都丟了,用戶罵一句“靠”忍氣吞聲重新打。如果每天遇到一次,可能還可以忍。如果有效期太短,如1小時,每天遇到5,6次,那用戶可能不干了,這時你可能要把未提交的訂單資料暫時存到localstorage里面。
  • 彈出登錄框。登錄框內容和代碼如何做,預先就加載了,每個頁面都有這部分,感覺很浪費,因為大部分時間用不上,動態從后臺加載,可能不好實現。
  • 登錄后把賬號密碼記錄在瀏覽器中,自動登錄。但基于安全考慮,一般是用戶特別勾選“記住我”,才會加密記錄賬號密碼到localstorage中,用戶下次打開瀏覽器時自動登錄。如果token過期就自動登錄,如何及時止損?后臺修改密碼或禁用賬號,如何同步到前端的localstorage中。大部分app是這么干的。以上3種都是要再次去后臺數據庫驗證,所以token過期時間不能太短,否則效率很差。
  • 設置refresh-token機制,頒發access-token時同時頒發一個refresh-token,唯一區別是refresh-token有效期比較長,比如1個月。當access-token過期后,拿著refresh-token到后臺換取新的access-token。通過在后臺為refresh-token設置黑名單來及時止損,所以有黑名單的時候,可能效率也會一樣的差。refresh-token也過期后,那就只有老老實實的讓用戶輸入賬號密碼登錄了,就是前面的1,2方法。因為refresh-token不常用,所以最好不要放在cookie中避免每次自動傳到后臺,放在localstorage較好。
    刷新access-token過程,如何讓用戶沒感覺?思路是:發現access-token,自動用refresh-token去刷新,然后再自動跳到原來頁面或者自動調用一次原來的ajax。
  • token身份驗證機制

    客戶端登錄請求成功后,服務器將用戶信息(如用戶id)使用特殊算法加密后作為驗證的標志發送給用戶(即token),當用戶下次發起請求時,會將這個token捎帶過來,服務器再將這個token通過解密后進行驗證,通過的話,則向客戶端返回請求的數據;反之,則請求失敗。

    token優點

    它是無狀態的,且服務器不用像傳統的身份認證(session)那樣需要保存會話信息,減輕了服務器的壓力。

    vue的token刷新處理

    在對token身份驗證機制進行一次簡單介紹后,進入正文…
    一般為了安全性,token都會設置一個過期時間,在過期之后就無法請求相關接口了,這時應該怎么辦呢,是直接退出登錄嗎?
    在目前公司的項目里,為了更好的用戶體驗,我們選擇手動刷新token。登錄請求成功后,會返回一個token和token過期時間,在每次請求api時,前端可以先判斷一下token是否即將過期或已過期,如果是,則請求刷新token的接口,成功替換原來的token之后才可以重新發起請求。
    下面,我們直接看代碼,這是在vue的請求攔截器里進行的相關操作:

    /*是否有請求正在刷新token*/window.isRefreshing = false;/*被掛起的請求數組*/let refreshSubscribers = [];/*獲取刷新token請求的token*/function getRefreshToken() {return JSON.parse(localStorage.auth).refresh_token;}/*push所有請求到數組中*/function subscribeTokenRefresh(cb) {refreshSubscribers.push(cb);}/*刷新請求(refreshSubscribers數組中的請求得到新的token之后會自執行,用新的token去請求數據)*/function onRrefreshed(token) {refreshSubscribers.map(cb => cb(token));}/*請求攔截器*/ajax.interceptors.request.use(config => {const authTmp = localStorage.auth;/*判斷是否已登錄*/if (authTmp) {/*解析登錄信息*/let auth = JSON.parse(authTmp);/*判斷auth是否存在*/if (auth) {/*在請求頭中添加token類型、token*/config.headers.Authorization = auth.token_type + " " + auth.token;/*判斷刷新token請求的refresh_token是否過期*/if (util.isRefreshTokenExpired()) {alert("刷新token過期,請重新登錄");/*清除本地保存的auth*/localStorage.removeItem("auth");window.location.href = "#/login";return;}/*判斷token是否將要過期*/if (util.isTokenExpired() &&config.url.indexOf("admin/auth/current") === -1) {/*判斷是否正在刷新*/if (!window.isRefreshing) {/*將刷新token的標志置為true*/window.isRefreshing = true;/*發起刷新token的請求*/apiList.refreshToken({ refresh_token: getRefreshToken() }).then(res => {/*將標志置為false*/window.isRefreshing = false;/*成功刷新token*/config.headers.Authorization =res.data.data.token_type + " " + res.data.data.token;/*更新auth*/localStorage.setItem("auth",JSON.stringify(res.data.data));/*執行數組里的函數,重新發起被掛起的請求*/onRrefreshed(res.data.data.token);/*執行onRefreshed函數后清空數組中保存的請求*/refreshSubscribers = [];}).catch(err => {alert(err.response.data.message);/*清除本地保存的auth*/// localStorage.removeItem('auth')window.location.href = "#/login";});}/*把請求(token)=>{....}都push到一個數組中*/let retry = new Promise((resolve, reject) => {/*(token) => {...}這個函數就是回調函數*/subscribeTokenRefresh(token => {config.headers.Authorization = "Bearer " + token;/*將請求掛起*/resolve(config);});});return retry;}}return config;} else {/*未登錄直接返回配置信息*/return config;}},/*錯誤操作*/err => {return Promise.reject(err);});

    這里需要注意幾點:
    1、當token即將過期或者已過期時,原則上,我們只需要有一個接口去觸發刷新token的請求即可,這里的isRefreshing 變量,就起到這樣一個監控的作用,它相當于一把鎖,當刷新token的操作被觸發后,其他的觸發操作就被排斥在外了。

    window.isRefreshing = false

    2、刷新token的接口,用到了一個另外的token(refresh_token),這也是出于安全性考慮的,并且它也有過期時間,不過這個過期時間一般都比普通token的過期時間要長,所以在上面代碼中,會發現,我在請求攔截中優先判斷了refresh_token是否過期,如果過期則直接退出登錄,不再進行下一步的操作。

    /*判斷刷新token請求的refresh_token是否過期*/ if (util.isRefreshTokenExpired() && config.url.indexOf('admin/auth/current') === -1) {alert('刷新token過期,請重新登錄')/*清除本地保存的auth*/localStorage.removeItem('auth')window.location.href = '#/login'return }

    3、在觸發了刷新token的操作后,我們還需要先將其他的請求掛起,在獲取新的token之后再重新發起這些請求。

    /*把請求(token)=>{....}都push到一個數組中*/ let retry = new Promise((resolve, reject) => {/*(token) => {...}這個函數就是回調函數*/subscribeTokenRefresh((token) => {config.headers.Authorization = 'Bearer ' + token/*將請求掛起*/resolve(config)}) }) return retry

    在刷新token請求的成功回調里執行下面代碼,重新發起請求。

    /*執行數組里的函數,重新發起被掛起的請求*/onRrefreshed(res.data.data.token)

    4、因為有人在評論里問util文件,應該是想知道具體怎么判斷token過期的,其實在獲得token時,是有返回一個token過期時間 ,你可以先將它先保存起來,然后在需要時,拿出來與本地時間比較即可

    /*判斷token是否過期*/ function isTokenExpired() {/*從localStorage中取出token過期時間*/let expiredTime = new Date(JSON.parse(localStorage.auth).expired_at).getTime() / 1000/*獲取本地時間*/let nowTime = new Date().getTime() / 1000/*獲取校驗時間差*/let diffTime = JSON.parse(sessionStorage.diffTime)/*校驗本地時間*/nowTime -= diffTime/*如果 < 10分鐘,則說明即將過期*/return (expiredTime - nowTime) < 10*60 }

    總結

    以上是生活随笔為你收集整理的vue的token刷新处理的全部內容,希望文章能夠幫你解決所遇到的問題。

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