您好,登錄后才能下訂單哦!
這篇文章主要介紹了無感知刷新Token是什么的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇無感知刷新Token是什么文章都會有所收獲,下面我們一起來看看吧。
在Web應(yīng)用中,常見的Token認(rèn)證方式有基于Cookie和基于Token的認(rèn)證?;贑ookie的認(rèn)證方式是將認(rèn)證信息保存在Cookie中,每次請求時將Cookie發(fā)送給服務(wù)器進(jìn)行認(rèn)證;而基于Token的認(rèn)證方式是將認(rèn)證信息保存在Token中,每次請求時將Token發(fā)送給服務(wù)器進(jìn)行認(rèn)證。
在基于Token的認(rèn)證方式中,客戶端將認(rèn)證信息保存在Token中,而不是保存在Cookie中。在認(rèn)證成功后,服務(wù)器將生成一個Access Token和一個Refresh Token,并將它們返回給客戶端。Access Token用于訪問受保護(hù)的API,Refresh Token用于獲取新的Access Token。
無感知刷新Token是指,在Token過期之前,系統(tǒng)自動使用Refresh Token獲取新的Access Token,從而實現(xiàn)Token的無感知刷新,用戶可以無縫繼續(xù)使用應(yīng)用。
在實現(xiàn)無感知刷新Token的過程中,需要考慮以下幾個方面:
如何判斷Token是否過期?
如何在Token過期時自動使用Refresh Token獲取新的Access Token?
如何處理Refresh Token的安全問題?
下面將介紹如何實現(xiàn)無感知刷新Token的具體步驟。
在認(rèn)證成功后,需要將Access Token和Refresh Token發(fā)送給客戶端。Access Token用于訪問受保護(hù)的API,Refresh Token用于獲取新的Access Token。可以使用JWT(JSON Web Token)或OAuth3(開放授權(quán))等方式實現(xiàn)認(rèn)證。
在JWT中,可以使用如下代碼生成Access Token和Refresh Token:
const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'}); const refreshToken = jwt.sign({userId: '123'}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});
在每個需要認(rèn)證的API請求中,需要在請求頭中攜帶Access Token,如下所示:
GET /api/user HTTP/1.1 Host: example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
在前端中,可以使用Axios等庫設(shè)置請求頭:
axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
在服務(wù)器返回401 Unauthorized響應(yīng)時,說明Access Token已經(jīng)過期,需要使用Refresh Token獲取新的Access Token??梢允褂肁xios攔截器或Fetch API的中間件實現(xiàn)攔截。
在Axios中,可以使用如下代碼實現(xiàn)攔截器:
axios.interceptors.response.use(response => { return response; }, error => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; //防止無限調(diào)用 return axios.post('/api/refresh_token', {refreshToken}) .then(response => { const { access_token, refresh_token } = response.data; localStorage.setItem('access_token', access_token); localStorage.setItem('refresh_token', refresh_token); axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`; originalRequest.headers.Authorization = `Bearer ${access_token}`; return axios(originalRequest); }); } return Promise.reject(error); });
在Fetch中,可以使用如下代碼實現(xiàn)中間件:
function authMiddleware(request) { const access_token = localStorage.getItem('access_token'); if (access_token) { request.headers.set('Authorization', `Bearer ${access_token}`); } return request; } function tokenRefreshMiddleware(response) { if (response.status === 401) { const refreshToken = localStorage.getItem('refresh_token'); return fetch('/api/refresh_token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken }) }).then(response => { if (response.ok) { return response.json(); } throw new Error('Refresh Token failed'); }).then(data => { localStorage.setItem('access_token', data.access_token); localStorage.setItem('refresh_token', data.refresh_token); return Promise.resolve('refreshed'); }).catch(error => { localStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); return Promise.reject(error); }); } return Promise.resolve('ok'); } fetch('/api/user', { method: 'GET', headers: { 'Content-Type': 'application/json' }, middleware: [authMiddleware, tokenRefreshMiddleware] }).then(response => { console.log(response); }).catch(error => { console.error(error); });
在上述代碼中,使用Axios或Fetch攔截器攔截401 Unauthorized響應(yīng),如果發(fā)現(xiàn)Access Token已經(jīng)過期,則發(fā)送Refresh Token請求獲取新的Access Token,并將新的Access Token設(shè)置到請求頭中,重新發(fā)送請求。
在服務(wù)器端,需要編寫API處理Refresh Token請求,生成新的Access Token,并返回給客戶端。
在JWT中,可以使用如下代碼生成新的Access Token:
const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
在刷新Token時,需要驗證Refresh Token的合法性,可以使用如下代碼驗證Refresh Token:
try { const payload = jwt.verify(refreshToken, 'REFRESH_TOKEN_SECRET'); const accessToken = jwt.sign({userId: payload.userId}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'}); const refreshToken = jwt.sign({userId: payload.userId}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'}); res.json({access_token: accessToken, refresh_token: refreshToken}); } catch (err) { res.sendStatus(401); }
在上述代碼中,使用JWT的verify
方法驗證Refresh Token的合法性,如果驗證成功,則生成新的Access Token和Refresh Token,并返回給客戶端。
為了避免Access Token過期時間太長,可以設(shè)置定時刷新Token的功能。可以使用定時器或Web Workers等方式實現(xiàn)定時刷新Token。在每次刷新Token時,需要重新獲取新的Access Token和Refresh Token,并保存到客戶端。
function refreshToken() { const refreshToken = localStorage.getItem('refresh_token'); axios.post('/api/refresh_token', {refreshToken}) .then(response => { const { access_token, refresh_token } = response.data; localStorage.setItem('access_token', access_token); localStorage.setItem('refresh_token', refresh_token); axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`; }) .catch(error => { console.error(error); }); } setInterval(refreshToken, 14 * 60 * 1000); // 每14分鐘刷新Token
在上述代碼中,使用定時器每14分鐘刷新Token。在刷新Token成功后,將新的Access Token和Refresh Token保存到客戶端,并將新的Access Token設(shè)置到請求頭中。
在實現(xiàn)無感知刷新Token的過程中,需要考慮到Refresh Token的安全性問題。因為Refresh Token具有長期的有效期限,一旦Refresh Token被泄露,攻擊者就可以使用Refresh Token獲取新的Access Token,從而繞過認(rèn)證機(jī)制,訪問受保護(hù)的API。
為了增加Refresh Token的安全性,可以考慮以下幾種措施:
將Refresh Token保存在HttpOnly Cookie中,可以避免在客戶端被JavaScript獲?。?/p>
對Refresh Token進(jìn)行加密或簽名,可以增加其安全性。
將Refresh Token保存在后端,前端通過接口和后端交互,實現(xiàn)刷新Access Token。
關(guān)于“無感知刷新Token是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“無感知刷新Token是什么”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。