ASP.NET Core中 JWT 實現無感刷新Token

在 Web 應用開發中,用戶登錄狀態的管理至關重要。為了避免用戶頻繁遇到登錄過期的問題,我們可以通過實現 JWT(JSON Web Token)刷新機制來提升用戶體驗

推薦: 使用 Refresh Token(雙 Token 機制)

1. 生成和使用雙 Token

通常會生成兩種 Token:訪問 Token (Access Token)?和?刷新 Token (Refresh Token)

  • ??訪問 Token:用于客戶端與服務器之間的身份驗證,有效期較短(例如 30 分鐘),以提高安全性。

  • ??刷新 Token:用于獲取新的訪問 Token,有效期較長(例如 7 天),存儲在客戶端 。

Tokenservice.cs:

?
// 生成 JWT Access Token 和 Refresh Token
public?(string?AccessToken,?string?RefreshToken) GenerateTokens(string?userId,?string?userName)
{var?tokenHandler =?new?JwtSecurityTokenHandler();var?key = Encoding.ASCII.GetBytes(_configuration["JwtSettings:Secret"]);// 生成 Access Tokenvar?accessTokenDescriptor =?new?SecurityTokenDescriptor{Subject =?new?ClaimsIdentity(new?Claim[]{new?Claim(ClaimTypes.NameIdentifier, userId),new?Claim(ClaimTypes.Name, userName)}),Issuer = _configuration["JwtSettings:Issuer"],Audience = _configuration["JwtSettings:Audience"],Expires = DateTime.UtcNow.AddMinutes(double.Parse(_configuration["JwtSettings:ExpireMinutes"])),SigningCredentials =?new?SigningCredentials(new?SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)};var?accessToken = tokenHandler.CreateToken(accessTokenDescriptor);// 生成 Refresh Tokenvar?refreshTokenDescriptor =?new?SecurityTokenDescriptor{Subject =?new?ClaimsIdentity(new?Claim[]{new?Claim(ClaimTypes.NameIdentifier, userId)}),Issuer = _configuration["JwtSettings:Issuer"],Audience = _configuration["JwtSettings:Audience"],Expires = DateTime.UtcNow.AddDays(7),?// Refresh Token 有效期 7 天SigningCredentials =?new?SigningCredentials(new?SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)};var?refreshToken = tokenHandler.CreateToken(refreshTokenDescriptor);return?(tokenHandler.WriteToken(accessToken), tokenHandler.WriteToken(refreshToken));
}// 根據舊 JWT 令牌換取新 JWT 令牌public?string?ExchangeJwtToken(string?oldToken){if?(!ValidateJwtToken(oldToken)){thrownew?InvalidOperationException("Invalid or expired token");}var?principal = ParseJwtToken(oldToken);var?userId = principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;var?userName = principal.FindFirst(ClaimTypes.Name)?.Value;if?(string.IsNullOrEmpty(userId) ||?string.IsNullOrEmpty(userName)){thrownew?InvalidOperationException("Invalid token claims");}return?GenerateJwtToken(userId, userName);}

AuthController.cs

private?readonly?TokenService _tokenService;
privatereadonly?IAppUser _appUser;public?AuthController(IConfiguration configuration, IAppUser appUser, TokenService tokenService)
{_tokenService = tokenService;_appUser = appUser;
}[HttpPost("login")]
[AllowAnonymous]
public?IActionResult?Login([FromBody] LoginRequest loginRequest)
{var?token = _tokenService.GenerateTokens(loginRequest.Username, loginRequest.Username);return?Ok(new?{ token.RefreshToken,token.AccessToken });
}

2. 前端請求攔截器自動刷新 Token

在前端應用中,可以使用請求攔截器來自動處理 Token 刷新邏輯。當訪問 Token 過期時,攔截器會自動調用刷新接口獲取新的訪問 Token,并重新發起請求

// ?請求攔截器
axios.interceptors.request.use(
config?=>?{const?token =?localStorage.getItem('accessToken');if?(token) {config.headers['Authorization'] =?`Bearer?${token}`;}return?config;},
error?=>?{returnPromise.reject(error);}
);axios.interceptors.response.use(
response?=>?response,
async?error => {const?originalRequest = error.config;if?(error.response.status?===?401?&& !originalRequest._retry) {originalRequest._retry?=?true;const?refreshToken =?localStorage.getItem('refreshToken');const?res =?await?axios.post('/api/auth/refresh-token', { refreshToken });localStorage.setItem('accessToken', res.data.accessToken);returnaxios(originalRequest);}returnPromise.reject(error);}
);

3. 后端提供刷新 Token 的接口

專門的接口來處理刷新 Token 的請求。該接口會驗證刷新 Token 的有效性,并返回新的訪問 Token

?// 刷新 Access Token
[HttpPost("refresh")]
public?IActionResult?RefreshToken([FromBody] RefreshTokenRequest request)
{try{var?validatetoken = _tokenService.ValidateJwtToken(request.RefreshToken);if?(validatetoken){return?Ok(_tokenService.ExchangeJwtToken(request.RefreshToken));}return?Unauthorized("Invalid refresh token");}catch?(Exception ex){return?Unauthorized("Invalid refresh token");}
}

不推薦:中間件自動刷新Token

  1. 1. 創建中間件:創建一個中間件,用于檢查每個請求的JWT Token過期時間。

  2. 2. 讀取Token:中間件讀取請求頭中的Authorization字段,獲取JWT Token。

  3. 3. 檢查過期時間:判斷Token的過期時間,如果距離過期時間在一定范圍內(如30分鐘內),則生成一個新的JWT Token,并通過自定義的響應頭(如X-Refresh-Token)返回給客戶端。

  4. 4. 客戶端更新Token:客戶端檢查響應頭,如果存在X-Refresh-Token,則用新Token替換舊Token,并在后續請求中使用新Token。

  5. 5. 弊端:雖然實現起來相對簡單,但安全性相對較低,因為Token的刷新是在客戶端自動進行的,如果Token被盜用,攻擊者可能會在Token過期前一直使用該Token

因為存在上述弊端,不推薦使用中間件自動刷新 Token,故不提供相關代碼實現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66623.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66623.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66623.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch(3.純python的實惠版)

前情: 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch(1.標準版)-CSDN博客 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch(2.換掉付費的Event Hubs)-CSDN博客 python腳本實現 厲害的…

python學opencv|讀取圖像(四十)掩模:三通道圖像的局部覆蓋

【1】引言 前序學習了使用numpy創建單通道的灰色圖像,并對灰色圖像的局部進行了顏色更改,相關鏈接為: python學opencv|讀取圖像(九)用numpy創建黑白相間灰度圖_numpy生成全黑圖片-CSDN博客 之后又學習了使用numpy創…

【全面解析】深入解析 TCP/IP 協議:網絡通信的基石

深入解析 TCP/IP 協議:網絡通信的基石 導語 你是否曾好奇,現代互聯網是如何實現全球設備之間的高速、穩定和可靠通信的?無論是瀏覽網頁、發送電子郵件,還是進行視頻通話,背后都離不開 TCP/IP 協議 的支撐。作為互聯網…

全面解析 Java 流程控制語句

Java學習資料 Java學習資料 Java學習資料 在 Java 編程中,流程控制語句是構建程序邏輯的關鍵部分,它決定了程序的執行順序和走向。通過合理運用這些語句,開發者能夠實現各種復雜的業務邏輯,讓程序更加靈活和智能。 順序結構 順…

Linux系統常用指令

查找文件 find / -name "<文件名>" 2>/dev/null //遍歷系統查找指定文件名文件ls -l | grep "<文件名>" //列出當前目錄下有關文件名的文件find -name sw_sfp_alarm_cfg.xml //查找文件名對應路徑 切換目錄 編輯文件 vi <文件…

【Unity】ScrollViewContent適配問題(Contentsizefilter不刷新、ContentSizeFilter失效問題)

最近做了一個項目&#xff0c;菜單欄讀取數據后自動生成&#xff0c;結果用到了雙重布局 父物體 嘗試了很多方式&#xff0c;也看過很多大佬的文章&#xff0c;后來自己琢磨了一下&#xff0c;當子物體組件自動生成之后&#xff0c;使用以下以下代碼效果會好一些&#xff1a; …

AI輔助醫學統計分析APP

AI輔助醫學統計分析APP 醫學統計分析的困難點在于開始階段分析的規劃和得出分析結果之后分析結果的解釋&#xff0c;前者之所以困難是因為分析方法繁多又有不同的使用條件&#xff0c;后者則是因為結果中術語較多&#xff0c;且各種分析方法術語又有不同&#xff0c;非統計專業…

[STM32 HAL庫]串口中斷編程思路

一、前言 最近在準備藍橋杯比賽&#xff08;嵌入式賽道&#xff09;&#xff0c;研究了以下串口空閑中斷DMA接收不定長的數據&#xff0c;感覺這個方法的接收效率很高&#xff0c;十分好用。方法配置都成功了&#xff0c;但是有一個點需要進行考慮&#xff0c;就是一般我們需要…

淺談Java之AJAX

一、基本介紹 在Java開發中&#xff0c;AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一種用于創建動態網頁的技術&#xff0c;它允許網頁在不重新加載整個頁面的情況下與服務器進行交互。 二、關鍵點和示例 1. AJAX的基本原理 AJAX通過JavaScript的XMLHtt…

AutoSar架構學習筆記

1.AUTOSAR&#xff08;Automotive Open System Architecture&#xff0c;汽車開放系統架構&#xff09;是一個針對汽車行業的軟件架構標準&#xff0c;旨在提升汽車電子系統的模塊化、可擴展性、可重用性和互操作性。AUTOSAR的目標是為汽車電子控制單元&#xff08;ECU&#xf…

算法競賽之差分進階——等差數列差分 python

目錄 前置知識進入正題實戰演練 前置知識 給定區間 [ l, r ]&#xff0c;讓我們把數組中的[ l, r ] 區間中的每一個數加上c,即 a[ l ] c , a[ l 1 ] c , a[ l 2] c , a[ r ] c; 怎么做&#xff1f;很簡單&#xff0c;差分一下即可 還不會的小伙伴點此進入學習 進入正題 …

TDengine 做 Apache SuperSet 數據源

?Apache Superset? 是一個現代的企業級商業智能&#xff08;BI&#xff09;Web 應用程序&#xff0c;主要用于數據探索和可視化。它由 Apache 軟件基金會支持&#xff0c;是一個開源項目&#xff0c;它擁有活躍的社區和豐富的生態系統。Apache Superset 提供了直觀的用戶界面…

金融場景 PB 級大規模日志平臺:中信銀行信用卡中心從 Elasticsearch 到 Apache Doris 的先進實踐

導讀&#xff1a;中信銀行信用卡中心每日新增日志數據 140 億條&#xff08;80TB&#xff09;&#xff0c;全量歸檔日志量超 40PB&#xff0c;早期基于 Elasticsearch 構建的日志云平臺&#xff0c;面臨存儲成本高、實時寫入性能差、文本檢索慢以及日志分析能力不足等問題。因此…

虛幻商城 Fab 免費資產自動化入庫

文章目錄 一、背景二、實現效果展示三、實現自動化入庫一、背景 上一次寫了個這篇文章 虛幻商城 Quixel 免費資產一鍵入庫,根據這個構想,便決定將范圍擴大,使 Fab 商城的所有的免費資產自動化入庫,是所有!所有! 上一篇文章是根據下圖這部分資產一鍵入庫: 而這篇文章則…

游戲為什么失敗?回顧某平庸游戲

1、上周玩了一個老鼠為主角的游戲&#xff0c;某平臺喜1送的&#xff0c; 下載了很久而一直沒空玩&#xff0c;大約1G&#xff0c;為了清硬盤空間而玩。 也是為了拔掉心中的一根刺&#xff0c;下載了而老是不玩總感覺不舒服。 2、老鼠造型比較寫實&#xff0c;看上去就有些討…

親測有效!如何快速實現 PostgreSQL 數據遷移到 時序數據庫TDengine

小T導讀&#xff1a;本篇文章是“2024&#xff0c;我想和 TDengine 談談”征文活動的優秀投稿之一&#xff0c;作者從數據庫運維的角度出發&#xff0c;分享了利用 TDengine Cloud 提供的遷移工具&#xff0c;從 PostgreSQL 數據庫到 TDengine 進行數據遷移的完整實踐過程。文章…

C#,入門教程(01)—— Visual Studio 2022 免費安裝的詳細圖文與動畫教程

通過本課程的學習&#xff0c;你可以掌握C#編程的重點&#xff0c;享受編程的樂趣。 在本課程之前&#xff0c;你無需具備任何C#的基礎知識&#xff0c;只要能操作電腦即可。 不過&#xff0c;希望你的數學不是體育老師教的。好的程序是數理化的實現與模擬。沒有較好的數學基礎…

Linux探秘坊-------3.開發工具詳解(2)

1.動靜態庫和動靜態鏈接&#xff08;操作&#xff09; 靜態庫是指編譯鏈接時,把庫?件的代碼全部加?到可執??件中,因此?成的?件 ?較?,但在運?時也就不再需要庫?件了。其后綴名?般為“.a” 動態庫與之相反,在編譯鏈接時并 沒有把庫?件的代碼加?到可執??件中 ,?…

電腦開機出現Bitlock怎么辦

目錄 1.前言 2.產生原因&#xff1a; 1.系統異常關機 2.系統更新錯誤 3.硬件更換 4.CMOS電池問題 5.出廠設置 6.意外情況 3.解鎖步驟&#xff1a; 3.1&#xff1a;記住密鑰ID&#xff08;前6位&#xff09; 3.2&#xff1a;打開aka.ms/myrecoverykey網址 3.3&#…

C# 的 NLog 庫高級進階

一、引言 在 C# 開發的廣袤天地中&#xff0c;日志記錄宛如開發者的 “千里眼” 與 “順風耳”&#xff0c;助力我們洞察應用程序的運行狀態&#xff0c;快速定位并解決問題。而 NLog 庫&#xff0c;無疑是日志記錄領域中的璀璨明星&#xff0c;以其強大的功能、靈活的配置和出…