上一章我們介紹了 JWT 的基本原理,接下來我們會建立一個 WebAPI 並透過他發行 JWT Token,然後將導入 Token 驗證的機制
建立 WebAssembly 專案#
開啟 Visual Studio 點選建立新專案並點選 Blazor WebAssembly
![選擇Blazor WebAssembly專案](https://i.imgur.com/KerNq8Y.png)
勾選 裝載在 ASP.NET Core 上
![勾選 裝載在 ASP.NET Core](https://i.imgur.com/xQdXBqv.png)
完成專案建立
發行 Token#
完成專案的建置後,我們要在網頁的後端做 JWT
- 安裝 NuGet 套件到 Blazor.Jwt.Server 專案內
1
| dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
|
在 Blazor.Jwt.Server 專案內,加入一個 API Controller
![](https://i.imgur.com/uHJn850.png)
這邊我取名為 AuthorizeController.cs
![](https://i.imgur.com/GO0D073.png)
修改Route Attribute
1
| [Route("api/[controller]/[action]")]
|
- 寫一個 GetToken 方法
這邊為了示範所以將邏輯都放在 Controller 內
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
| [HttpGet]
public IActionResult GetToken(string userName)
{
var key = "2022/09/28 IThome 鐵人賽";
var claims = new List<Claim>
{
// 使用者名稱
new (JwtRegisteredClaimNames.Sub,userName),
// Token Id
new (JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
};
var claimsIdentity = new ClaimsIdentity(claims);
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = "發行者",
Subject = claimsIdentity,
Expires = DateTime.UtcNow.AddMinutes(30),
SigningCredentials = signingCredentials
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(securityToken));
}
|
- 呼叫API 取得Token
https://localhost:7102/api/Authorize/GetToken?username=JimWang
![](https://i.imgur.com/X1BhWjL.png)
恭喜 ! 做到這邊就成功發行了 JWT Token ,我們拿去解析下
![](https://i.imgur.com/7Asco7C.png)
- nbf 代表從這個時間以前無效
- exp 有效期限
- iat 發行時間
驗證 Token#
我們發行了 Token 下一個問題點在於,當使用者拿著 Token 來的時候,我該怎麼驗證這份 Token
- 一樣是 Blazor.Jwt.Server 專案內,在
Program.cs
中加入服務
1
2
3
4
5
6
7
8
9
10
11
12
| builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
ValidateIssuer = true,
ValidIssuer = "發行者",
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("2022/09/28 IThome 鐵人賽"))
};
});
|
這邊的 option 有非常多的設定可以調整,要注意需要填入簽名使用的 key
,如果有驗證發行者alidateIssuer = true
,也需要填入生產Token時的發行者
- 加入驗證服務
1
| builder.Services.AddAuthorization();
|
- 最後在下方
app
的部分加入兩行
1
2
| app.UseAuthentication();
app.UseAuthorization();
|
注意順序不可以錯誤 先驗證再授權!!!
套用 JWT#
我們完成了發行以及驗證,可是好像還沒有用上,最後一個步驟做整合,讓我們的 WebAPI 受到身分驗證的保護
- 回到
AuthorizeController.cs
再加入一個新的 action
1
2
3
4
5
6
| [HttpGet]
[Authorize]
public IActionResult GetUserInfo()
{
return Ok("取得使用者資料");
}
|
呼叫 GetUserInfo()
會發現回覆的 HttpStatusCode 從 200 變成 401,因為我這一個請求沒有帶入Token,所以伺服器直接回覆我 Code 401,接著我們再試著帶入 Token 並且執行
帶入 Token
![](https://i.imgur.com/1iqKSfq.png)
呼叫成功
![](https://i.imgur.com/xKjBEOh.png)
明天我們會在 Blazor WebAssembly 練習取得 Token ,並且請求(Request) 中一起帶入 Token,取得伺服器的資源