在這篇中主要實作JWT的登入認證,取得Token、透過Token對有權限的API進行存取。
安裝
1.先安裝JWT套件,因為我是用AspNetCore所以用
Microsoft.AspNetCore.Authentication.JwtBearer
撰寫
1.撰寫產生JWT Token的程式碼。
TokenController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| [HttpPost("GenerateToken")] [AllowAnonymous] public ActionResult<string> GenerateToken() { string issuer = "JwtAuthDemo"; string signKey = "ASASA1@AAASASASASA1@AAASAS"; // 需要大於16字元 string Account = "TestAccount"; var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey)); var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
// 建立 SecurityTokenDescriptor var tokenDescriptor = new SecurityTokenDescriptor { Issuer = issuer, Subject = new ClaimsIdentity(new[] { new Claim(JwtRegisteredClaimNames.Sub, Account), // User.Identity.Name new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), // JWT ID new Claim("test", "123") // 可加入自訂內容在聲明裡 }), Expires = DateTime.Now.AddMinutes(60), SigningCredentials = signingCredentials }; var tokenHandler = new JwtSecurityTokenHandler(); var securityToken = tokenHandler.CreateToken(tokenDescriptor); var serializeToken = tokenHandler.WriteToken(securityToken); return serializeToken; }
|
2.撰寫測試JWT請求的程式碼
在此撰寫兩個一個是取得所有聲明,一個是取得該Token得獨立識別值。
TokenController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| [Authorize] [HttpGet("GetClaims")] public IActionResult GetClaims() { return Ok(User.Claims.Select(p => new { p.Type, p.Value })); }
[Authorize] [HttpGet("GetTokenID")] public IActionResult GetTokenID() { var jti = User.Claims.FirstOrDefault(p => p.Type == "jti");//每個token的識別值,如果要禁用某token就可以把識別值存到資料庫當黑名單 return Ok(jti.Value); }
|
3.增加服務
Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public void ConfigureServices(IServiceCollection services){
services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { // 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因 options.IncludeErrorDetails = true; // 預設值為 true,有時會特別關閉
options.TokenValidationParameters = new TokenValidationParameters {
// 一般我們都會驗證 Issuer ValidateIssuer = true, ValidIssuer = "JwtAuthDemo",
// 通常不太需要驗證 Audience ValidateAudience = false, //ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫
// 一般我們都會驗證 Token 的有效期間 ValidateLifetime = true,
// 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已 ValidateIssuerSigningKey = false,
// JWT簽證密要,之後可自行設定在appsettings.json IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ASASA1@AAASASASASA1@AAASAS")) }; });
}
|
4.添加授權
1 2 3 4 5 6
| public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider) { app.UseAuthentication(); app.UseAuthorization();
}
|
5.完成測試結果:
取得Token
用剛剛產生的JWT Token取得聲明
用剛剛產生的JWT Token取得Token識別值
總結
C#在處理JWT上算是蠻簡潔的,不用寫太多行,主要複雜點就在Startup.cs增加服務、產生Token這兩個步驟。
專案存庫位置:https://github.com/yuhsiang237/ASP.NET-Core-RESTfulAPI-JWT
然後附上DEMO影片一個是用Postman測試,一個是程式碼跑起的時的Swagger
swagger demo:
postman demo: