在現代網站開發中,JSON Web Tokens(JWT)是一種流行的身份驗證和授權機制。以下簡單說明JWT的流程
用戶身份驗證
- 用戶輸入資料:用戶在登入表單中輸入他們的憑證,例如用戶名和密碼。
- 伺服器驗證:伺服器接收到憑證後,會在資料庫中驗證用戶的身份。
生成JWT
- 成功驗證後:一旦用戶被成功驗證,伺服器會創建一個JWT。
- JWT結構:JWT通常包含三部分:頭部(Header)、有效負載(Payload)、和簽名(Signature)。
- 頭部:指定了令牌的類型(通常是JWT)和所使用的簽名算法,如HMAC SHA256或RSA。
- 有效負載:包含聲明(claims),聲明是關於實體(通常是用戶)和其他數據的陳述。例如,用戶ID、用戶名、過期時間等。
- 簽名:對頭部和有效負載進行簽名,以驗證消息在傳輸過程中未被篡改。
發送JWT給用戶
- 客戶端存儲:伺服器將JWT發送回用戶,用戶端應用程式(如瀏覽器)會將其存儲在本地,通常是在Cookie或LocalStorage中。
JWT的使用
- 隨請求發送:之後,當用戶向伺服器發送請求時,會將JWT附加在HTTP請求的授權頭部中。
- 伺服器驗證JWT:伺服器會驗證接收到的JWT的簽名,以確保它是有效和可信的。
- 授權和存取控制:伺服器根據JWT中的資訊(如用戶角色)進行授權和存取控制。
JWT過期處理
- 過期機制:JWT通常包含過期時間。一旦過期,用戶需要重新登入以獲得新的JWT。
- 刷新令牌:在某些實現中,系統可能會提供刷新令牌(Refresh Token),用於在不需要用戶重新登入的情況下更新JWT。
優點與考量
- 無狀態和可擴展性:由於JWT自包含所有用戶信息,伺服器不需要維護用戶的登入狀態,這對於構建可擴展的應用程式很有幫助。
- 安全性考量:雖然JWT提供了方便的身份驗證機制,但它也帶來了安全挑戰,如JWT的安全存儲、防止XSS和CSRF攻擊等。

如何安裝和使用JWT
安裝底下套件
Microsoft.AspNetCore.Authentication.JwtBearer
System.IdentityModel.Tokens.Jwt
或下指令
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
1.建立一個使用者模型
public class User
{
public string Username { get; set; }
public string Password { get; set; }
}
2. 創建一個控制器來處理登入請求
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly string _key = "ThisIsASecretKeyForJwt";
[HttpPost("login")]
public IActionResult Login([FromBody] User user)
{
// 模擬使用者驗證
if (user.Username == "admin" && user.Password == "password")
{
var token = GenerateJwtToken(user.Username);
return Ok(new { Token = token });
}
return Unauthorized("Invalid credentials");
}
private string GenerateJwtToken(string username)
{
var claims = new[]
{
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "yourdomain.com",
audience: "yourdomain.com",
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
3. 配置 JWT 中間件驗證
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 添加 JWT 驗證中間件
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "yourdomain.com",
ValidAudience = "yourdomain.com",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ThisIsASecretKeyForJwt"))
};
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. 建立一個受保護的 API 端點
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class ProtectedController : ControllerBase
{
[HttpGet]
[Authorize]
public IActionResult GetSecret()
{
var username = User.Identity?.Name;
return Ok($"Hello, {username}! This is a protected message.");
}
}
測試
啟動應用程式,發送一個登入請求:
URL: http://localhost:5000/api/auth/login
Method: POST
Body:
{
"username": "admin",
"password": "password"
}
使用返回的 Token 測試受保護的端點:
URL: http://localhost:5000/api/protected
Method: GET
Headers:Authorization: Bearer [Your JWT Token]
總結
JWT這套機制具有輕量、跨平台的優勢,在現代應用中實現身份認證與授權是不可或缺的套件。趕快動手試試吧!