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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core Web Api之JWT刷新Token(三)

發(fā)布時間:2023/12/4 asp.net 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core Web Api之JWT刷新Token(三) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本節(jié)我們進入JWT最后一節(jié)內(nèi)容,JWT本質(zhì)上就是從身份認(rèn)證服務(wù)器獲取訪問令牌,繼而對于用戶后續(xù)可訪問受保護資源,但是關(guān)鍵問題是:訪問令牌的生命周期到底設(shè)置成多久呢?
見過一些使用JWT的童鞋會將JWT過期時間設(shè)置成很長,有的幾個小時,有的一天,有的甚至一個月,這么做當(dāng)然存在問題,如果被惡意獲得訪問令牌,那么可在整個生命周期中使用訪問令牌,也就是說存在冒充用戶身份,此時身份認(rèn)證服務(wù)器當(dāng)然也就是始終信任該冒牌訪問令牌
若要使得冒牌訪問令牌無效,唯一的方案則是修改密鑰,但是如果我們這么做了,則將使得已授予的訪問令牌都將無效,所以更改密鑰不是最佳方案,我們應(yīng)該從源頭盡量控制這個問題,而不是等到問題呈現(xiàn)再來想解決之道,刷新令牌閃亮登場。


什么是刷新令牌呢?刷新訪問令牌是用來從身份認(rèn)證服務(wù)器交換獲得新的訪問令牌,有了刷新令牌可以在訪問令牌過期后通過刷新令牌重新獲取新的訪問令牌而無需客戶端通過憑據(jù)重新登錄,如此一來,既保證了用戶訪問令牌過期后的良好體驗,也保證了更高的系統(tǒng)安全性
同時,若通過刷新令牌獲取新的訪問令牌驗證其無效可將受訪者納入黑名單限制其訪問,那么訪問令牌和刷新令牌的生命周期設(shè)置成多久合適呢?這取決于系統(tǒng)要求的安全性,一般來講訪問令牌的生命周期不會太長,比如5分鐘,又比如獲取微信的AccessToken的過期時間為2個小時。
接下來我將用兩張表來演示實現(xiàn)刷新令牌的整個過程,可能有更好的方案,歡迎在評論中提出,學(xué)習(xí),學(xué)習(xí)。我們新建一個http://localhost:5000的WebApi用于身份認(rèn)證,再新建一個http://localhost:5001的客戶端,首先點擊【模擬登錄獲取Toen】獲取訪問令牌和刷新令牌,然后點擊【調(diào)用客戶端獲取當(dāng)前時間】,如下:


接下來我們新建一張用戶表(User)和用戶刷新令牌表(UserRefreshToken),結(jié)構(gòu)如下:如上可以看到對于刷新令牌的操作我們將其放在用戶實體中,也就是使用EF Core中的Back Fields而不對外暴露。接下來我們將生成的訪問令牌、刷新令牌、驗證訪問令牌、獲取用戶身份封裝成對應(yīng)方法如下:當(dāng)用戶點擊登錄,訪問身份認(rèn)證服務(wù)器,登錄成功后我們創(chuàng)建訪問令牌和刷新令牌并返回,如下:此時我們回到如上給出的圖,我們點擊【模擬登錄獲取Token】,此時發(fā)出Ajax請求,然后將返回的訪問令牌和刷新令牌存儲到本地localStorage中,如下:此時我們再來點擊【調(diào)用客戶端獲取當(dāng)前時間】,同時將登錄返回的訪問令牌設(shè)置到請求頭中,代碼如下:客戶端請求接口很簡單,為了讓大家一步步看明白,我也給出來,如下:好了到了這里我們已經(jīng)實現(xiàn)模擬登錄獲取訪問令牌,并能夠調(diào)用客戶端接口獲取到當(dāng)前時間,同時我們也只是返回了刷新令牌并存儲到了本地localStorage中,并未用到。當(dāng)訪問令牌過期后我們需要通過訪問令牌和刷新令牌去獲取新的訪問令牌,對吧。
那么問題來了。我們怎么知道訪問令牌已經(jīng)過期了呢?這是其一,其二是為何要發(fā)送舊的訪問令牌去獲取新的訪問令牌呢?直接通過刷新令牌去換取不行嗎?有問題是好的,就怕沒有任何思考,我們一一來解答。我們在客戶端添加JWT中間件時,里面有一個事件可以捕捉到訪問令牌已過期(關(guān)于客戶端配置JWT中間件第一節(jié)已講過,這里不再啰嗦),如下:通過如上事件并捕捉訪問令牌過期異常,這里我們在響應(yīng)頭添加了一個自定義鍵act,值為expired,因為一個401只能反映未授權(quán),并不能代表訪問令牌已過期。當(dāng)我們在第一張圖中點擊【調(diào)用客戶端獲取當(dāng)前時間】發(fā)出Ajax請求時,如果訪問令牌過期,此時在Ajax請求中的error方法中捕捉到,我們在如上已給出發(fā)出Ajax請求的error方法中繼續(xù)進行如下補充:到了這里我們已經(jīng)解決如何捕捉到訪問令牌已過期的問題,接下來我們需要做的則是獲取刷新令牌,直接通過刷新令牌換取新的訪問令牌也并非不可,只不過還是為了安全性考慮,我們加上舊的訪問令牌。接下來我們發(fā)出Ajax請求獲取刷新令牌,如下:發(fā)出Ajax請求獲取刷新令牌的方法我們傳入了一個函數(shù),這個函數(shù)則是上一次調(diào)用接口訪問令牌過期的請求,點擊【調(diào)用客戶端獲取當(dāng)前時間】按鈕的Ajax請求error方法中,最終演變成如下這般:接下來則是通過傳入舊的訪問令牌和刷新令牌調(diào)用接口換取新的訪問令牌,如下:如上通過傳入舊的訪問令牌驗證并獲取用戶身份,然后驗證刷新令牌是否已經(jīng)過期,如果未過期則創(chuàng)建新的訪問令牌,同時更新刷新令牌。最終客戶端訪問令牌過期的那一刻,通過刷新令牌獲取新的訪問令牌繼續(xù)調(diào)用上一請求,如下:


到這里關(guān)于JWT實現(xiàn)刷新Token就已結(jié)束,自我感覺此種實現(xiàn)刷新令牌將其存儲到數(shù)據(jù)庫的方案還算可取,將刷新令牌存儲到Redis也可行,看個人選擇吧。上述若刷新令牌驗證無效,可將訪問者添加至黑名單,不過是添加一個屬性罷了。別著急,本節(jié)內(nèi)容結(jié)束前,還留有彩蛋。


無論是看視頻還是看技術(shù)博客也好,一定要動手驗證,看到這里覺得上述我所演示是不是毫無問題,如果閱讀本文的你直接拷貝上述代碼你會發(fā)現(xiàn)有問題,且聽我娓娓道來,讓我們來復(fù)習(xí)下Back Fields。Back Fields命名是有約定dei,上述我是根據(jù)約定而命名,所以千萬別一意孤行,別亂來,比如如下命名將拋出如下異常:上述我們配置刷新令牌的Back Fields,代碼如下:要是我們配置成如下形式,結(jié)果又會怎樣呢?此時為了解決這個問題,我們必須將其顯式配置成Back Fields,如下:在我個人著作中也講解到為了性能問題,可將字段進行ToList(),若進行了ToList(),必須顯式配置成Back Fields,否則獲取不到刷新令牌導(dǎo)航屬性,如下:或者進行如下配置,我想應(yīng)該也可取,不會存在性能問題,如下:這是關(guān)于Back Fields問題之一,問題之二則是上述我們請求獲取刷新令牌中,我們先在刷新令牌的Back Fields中移除掉舊的刷新令牌,而后再創(chuàng)建新的刷新令牌,但是會拋出如下異常:我們看到在添加刷新令牌時,用戶Id是有值的,對不對,這是為何呢?究其根本問題出在我們移除刷新令牌方法中,如下:我們將查詢出來的導(dǎo)航屬性并將其映射到_userRefreshTokens字段中,此時是被上下文所追蹤,上述我們查詢出存在的刷新令牌并在跟蹤的刷新令牌中進行移除,沒毛病,沒找到原因,于是乎,我將上述方法修改成如下看看是否必須需要主鍵才能刪除舊的刷新令牌:倒沒拋出異常,創(chuàng)建了一個新的刷新令牌,但是舊的刷新令牌卻沒刪除,如下:至此未找到問題出在哪里,當(dāng)前版本為2.2,難道不能通過Back Fields移除對象?這個問題待解決。


本節(jié)我們重點講解了如何實現(xiàn)JWT刷新令牌,并也略帶討論了EF Core中Back Fields以及尚未解決的問題,至此關(guān)于JWT已結(jié)束,下節(jié)開始正式進入Docker小白系列,感謝閱讀。


創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的ASP.NET Core Web Api之JWT刷新Token(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。