在現代 Web 應用中,安全認證是確保使用者資料和系統安全的重要一環。JSON Web Token (JWT) 是一種流行的認證方式,它可以在客戶端和服務端之間安全地傳遞資訊。本文將詳細介紹 JWT Bearer 認證的概念、工作原理、在 .NET Core 中的實現步驟,以及最佳實踐。
一、什麼是 JWT?
JSON Web Token (JWT) 是一個開放標準(RFC 7519),用於以安全的方式在網路應用環境中傳遞宣告資訊。JWT 的基本結構由三個部分組成:
-
頭部 (Header):通常包含令牌的型別(JWT)和所使用的簽名演算法(如 HMAC SHA256)。
-
負載 (Payload):包含要傳遞的資料,稱為宣告 (Claims),可以是關於使用者的資訊或其他後設資料。
-
簽名 (Signature):透過將編碼後的頭部和負載與一個金鑰結合,使用指定的演算法生成的簽名,用於驗證令牌的真實性。
JWT 的結構示例如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
二、JWT Bearer 認證的工作原理
在 JWT Bearer 認證中,使用者透過提供憑據(如使用者名稱和密碼)進行身份驗證。以下是基本的工作流程:
-
使用者登入:使用者傳送登入請求,附帶使用者名稱和密碼。
-
生成 JWT:伺服器驗證憑據後生成 JWT,並將其返回給使用者。
-
使用 JWT:使用者在後續的 API 請求中,將 JWT 作為 Bearer Token 傳送。
-
驗證 JWT:伺服器接收到請求後,驗證 JWT 的有效性。如果有效,則允許訪問相應的資源。
JWT 的優勢在於它是自包含的,包含了所有使用者所需的資訊,無需在伺服器上儲存會話狀態。
三、在 .NET Core 中實現 JWT Bearer 認證
1. 安裝所需 NuGet 包
在您的 .NET Core 專案中安裝 JWT Bearer 認證所需的 NuGet 包:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt
2. 配置 JWT 認證服務
在 Program.cs
檔案中配置 JWT Bearer 認證。以下是完整示例:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 讀取 JWT 配置
var jwtSection = builder.Configuration.GetSection("JwtSettings");
var key = jwtSection.GetValue<string>("Key");
var issuer = jwtSection.GetValue<string>("Issuer");
var audience = jwtSection.GetValue<string>("Audience");
// 配置 JWT 認證
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
ValidAudience = audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
};
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseAuthentication(); // 使用認證中介軟體
app.UseAuthorization(); // 使用授權中介軟體
app.MapControllers(); // 對映控制器
app.Run();
3. 在 appsettings.json
中配置 JWT 設定
在 appsettings.json
中新增 JWT 的配置:
{
"JwtSettings": {
"Key": "dsggdgewt3452345sbvsdgsdfsvxGHLKGFFJHLL", // 生成 JWT 所用的金鑰
"Issuer": "mywebapiTest", // JWT 的頒發者
"Audience": "mywebapiTest" // JWT 的接收者
},
"AllowedHosts": "*"
}
4. 生成 JWT
在使用者成功登入後生成 JWT。可以建立一個控制器處理登入請求:
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace MyApp.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IConfiguration _configuration;
public AuthController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel login)
{
// 驗證使用者身份(示例中使用簡單的硬編碼,實際應呼叫資料庫驗證)
if (login.Username == "test" && login.Password == "password")
{
var claims = new[]
{
new Claim(ClaimTypes.Name, login.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtSettings:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _configuration["JwtSettings:Issuer"],
audience: _configuration["JwtSettings:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(30), // 設定過期時間
signingCredentials: creds);
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
}
return Unauthorized(); // 認證失敗
}
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}
5. 保護 API 端點
可以透過 [Authorize]
特性保護需要身份驗證的 API 端點:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace MyApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[Authorize] // 保護此 API
[HttpGet]
public IActionResult Get()
{
return Ok(new { Weather = "Sunny" });
}
}
}
四、測試 JWT Bearer 認證
-
登入:傳送 POST 請求到
/api/auth/login
,使用 JSON 格式的使用者名稱和密碼進行身份驗證。成功後將返回一個 JWT。示例請求體:
{
"username": "test",
"password": "password"
} -
訪問受保護的 API:在請求頭中新增
Authorization
欄位,格式為Bearer {token}
。示例請求:
GET /weatherforecast HTTP/1.1
Authorization: Bearer {your_token}
五、最佳實踐
-
金鑰管理:確保 JWT 的金鑰安全,不要將其硬編碼在程式碼中。可以使用環境變數或金鑰管理服務。
-
過期時間:合理設定 JWT 的過期時間,以防長期有效的令牌被濫用。
-
黑名單機制:在使用者登出或更改密碼時,考慮實現黑名單機制,以便失效舊的 JWT。
-
HTTPS:始終透過 HTTPS 傳輸 JWT,防止中間人攻擊。
六、總結
JWT Bearer 認證為 .NET Core 應用程式提供了一種簡單、安全的身份驗證方式。透過本教程,您可以瞭解如何在 .NET Core 中實現 JWT 認證,從基本配置到實際應用,掌握 JWT 的使用。這種認證機制不僅提高了安全性,還增強了 API 的靈活性和可擴充套件性。希望您在專案中能夠順利實現 JWT Bearer 認證,提升應用的安全性與使用者體驗。
jwt解析: