在前后端分離的架構中,前端需要通過 API 介面的方式獲取資料,但 API 是無狀態的,沒有辦法知道每次請求的身份,也就沒有辦法做權限的控制,如果不做控制,API 就對任何人敞開了大門,只要拿到了介面地址就可以進行呼叫,這是非常危險的,本文主要介紹下在 dotNET Core Web API 中使用 Jwt 來實作介面的認證,
Jwt 簡介
Jwt 的全稱是 JSON Web Token,是目前比較流行的介面認證解決方案,有了 Jwt 后,從客戶端請求介面的流程如下圖:

- 客戶端發送用戶名密碼資訊到認證服務器獲取 token;
- 客戶端請求 API 獲取資料時帶上 token;
- 服務器端驗證 token,合法則回傳正確的資料,
有一個網站叫:https://jwt.io/ ,我們在這個站點上對 Jwt 產生的 token 做驗證:

從上圖可以看出 Jwt 生產的 token 由三個部分組成:
- Header(紅色):頭
- Playload(紫色):負載
- Verify Sigantuer(藍色):簽名
這三個部分由英文的點進行分隔開
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2VjMjAwMyIsInNpdGUiOiJodHRwOi8vZndoeXkuY29tIiwiaWF0IjoxNTE2MjM5MDIyfQ.DYgo4eEUwlYJqQoLvAuFPxFRVcCow77Zyl2byaK6Uxk
Header
頭資訊是一個 Json 格式的資料
{
"alg": "HS256",
"typ": "JWT"
}
- alg:表示加密的演算法
- typ:表示 token 的型別
Playload
Playload 是 token 的主體內容部分,我們可以用來傳遞一些資訊給客戶端,比如過期時間就是通過 Playload 來進行傳遞的, 但因為默認情況下 Playload 的資料是明文的,所以敏感資訊不要放在這里,
Verify Sigantuer
Verify Sigantuer 是對前面兩個部分的簽名,防止資料篡改,
使用 Jwt
下面一步步介紹在 dotNET Core Web API 專案中使用 Jwt:
添加 Jwt 的包參考
在 Web API 專案中添加對 Microsoft.AspNetCore.Authentication.JwtBearer 包的參考

修改 Starup
1、在 ConfigureServices 方法中添加服務注冊,
// jwt 認證
JwtSettings jwtSettings = new JwtSettings();
services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));
Configuration.GetSection("JwtSettings").Bind(jwtSettings);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o=>
{
o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
//用于簽名驗證
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.SecretKey)),
ValidateIssuer = false,
ValidateAudience = false
};
});
JwtSettings 的配置設定在 appsettings.json 組態檔中:

2、在 Configure 方法中添加對中間件的使用,
app.UseAuthentication();
app.UseAuthorization();
添加認證介面
添加 AuthorizeController 控制器:
[ApiController]
public class AuthorizeController: BaseController
{
private readonly IUserService _userService;
private readonly JwtSettings _jwtSettings;
public AuthorizeController(IMapper mapper,
IUserService userService,
IOptions<JwtSettings> options) : base(mapper)
{
_userService = userService;
_jwtSettings = options.Value;
}
/// <summary>
/// 獲取 token
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public string Token(TokenDto request)
{
bool isValidate = _userService.ValidatePassword(request.UserName, request.Password);
if(!isValidate) return string.Empty;
var claims = new Claim[]{
new Claim(ClaimTypes.Name,request.UserName)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_jwtSettings.Issuer,
_jwtSettings.Audience,
claims,
DateTime.Now,
DateTime.Now.AddSeconds(10),
creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
上面代碼中使用 IOptions 來做強型別配置,將 JwtSettings 配置類注入到該控制器中使用,關于更多配置內容可以參考:《dotNET Core 配置》,
使用 Postman 測驗
1、在需要進行認證的控制器或介面方法上添加 [Authorize] 標記,

2、呼叫介面 http://localhost:5000/api/Authorize/token 獲取 token,

3、在請求介面時使用 Authorization 的方式使用 token,token 的型別為 Bearer Token ,可以看到帶上 token 后,資料正常回傳,

在 Vue 中呼叫
前端技術有很多種,在這里以 Vue 為例,Vue 中處理 Jwt 有以下幾個步驟:
1、請求介面時判斷 localStorage 中是否有 token 資料,沒有 token 資料或者 token 已經過期,需要重新呼叫介面獲取新的 token;
2、使用 axios 的攔截器,在所有請求的 Header 中都添加 Authorization,
示例代碼:
- Vue:https://github.com/oec2003/vue-jwt-demo
- 介面:https://github.com/oec2003/DotNetCoreThreeAPIDemo
希望本文對您有所幫助,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/40671.html
標籤:.NET Core
下一篇:一站式WebAPI與認證授權服務
