<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在前後端分離的應用中,使用Token進行認證是一種較為常見的方式。但是,由於Token的有效期限制,需要不斷重新整理Token,否則會導致使用者認證失敗。為了解決這個問題,可以實現無感知重新整理Token的功能,本文將介紹如何實現無感知重新整理Token。
在Web應用中,常見的Token認證方式有基於Cookie和基於Token的認證。基於Cookie的認證方式是將認證資訊儲存在Cookie中,每次請求時將Cookie傳送給伺服器進行認證;而基於Token的認證方式是將認證資訊儲存在Token中,每次請求時將Token傳送給伺服器進行認證。
在基於Token的認證方式中,使用者端將認證資訊儲存在Token中,而不是儲存在Cookie中。在認證成功後,伺服器將生成一個Access Token和一個Refresh Token,並將它們返回給使用者端。Access Token用於存取受保護的API,Refresh Token用於獲取新的Access Token。
無感知重新整理Token是指,在Token過期之前,系統自動使用Refresh Token獲取新的Access Token,從而實現Token的無感知重新整理,使用者可以無縫繼續使用應用。
在實現無感知重新整理Token的過程中,需要考慮以下幾個方面:
下面將介紹如何實現無感知重新整理Token的具體步驟。
在認證成功後,需要將Access Token和Refresh Token傳送給使用者端。Access Token用於存取受保護的API,Refresh Token用於獲取新的Access Token。可以使用JWT(JSON Web Token)或OAuth2(開放授權)等方式實現認證。
在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'});
在每個需要認證的API請求中,需要在請求頭中攜帶Access Token,如下所示:
GET /api/user HTTP/1.1 Host: example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
在前端中,可以使用Axios等庫設定請求頭:
axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
在伺服器返回401 Unauthorized響應時,說明Access Token已經過期,需要使用Refresh Token獲取新的Access Token。可以使用Axios攔截器或Fetch API的中介軟體實現攔截。
在Axios中,可以使用如下程式碼實現攔截器:
axios.interceptors.response.use(response => { return response; }, error => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; //防止無限呼叫 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中,可以使用如下程式碼實現中介軟體:
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響應,如果發現Access Token已經過期,則傳送Refresh Token請求獲取新的Access Token,並將新的Access Token設定到請求頭中,重新傳送請求。
在伺服器端,需要編寫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過期時間太長,可以設定定時重新整理Token的功能。可以使用定時器或Web Workers等方式實現定時重新整理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設定到請求頭中。
在實現無感知重新整理Token的過程中,需要考慮到Refresh Token的安全性問題。因為Refresh Token具有長期的有效期限,一旦Refresh Token被洩露,攻擊者就可以使用Refresh Token獲取新的Access Token,從而繞過認證機制,存取受保護的API。
為了增加Refresh Token的安全性,可以考慮以下幾種措施:
以上就是無感知重新整理Token的詳細內容,更多關於無感知重新整理Token的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45