.net core集成JWT(基礎)
- 2020 年 11 月 14 日
- 筆記
- JWT, .Net/.Net Core, net jwt, net core jwt
關於JWT的基本概念,如果有不清晰的同學,請點擊這裡,就不在這裡贅述了。接下來聊聊JWT是怎麼發揮作用的。
第一,安裝nuget包
Microsoft.AspNetCore.Authentication.JwtBearer
第二,配置【Startup】
首先是【ConfigureServices】方法,下面要寫一大堆進去
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
LifetimeValidator = (notBefore, expires, securityToken, validationParameters) =>
{
bool t = DateTime.UtcNow < expires;
return t;
},
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuer = jwtConfig.Issuer,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.Key)),
};
});
雖然看起來多,實際上邏輯很清晰,我在這裡簡單解釋一下:
RequireHttpsMetadata:獲取或設置元數據地址或許可權是否需要HTTPS,默認為true
SaveToken:是否將資訊存儲在token中
TokenValidationParameters:這部分網上有很多版本,其中大部分都是寫滿的,但這對新手不太友好;而且也不是必須寫滿。先解釋一些程式碼里的驗證開關(設置true、false的我稱為驗證開關)
ValidateLifetime——是否驗證過期時間
ValidateAudience——是否驗證被發布者
ValidateIssuer——是否驗證發布者
ValidateIssuerSigningKey——是否驗證簽名
查看框架程式碼你會發現更多的驗證開關,這裡就不一一解釋了:

然後在【Configure】添加引用:
app.UseAuthentication();
app.UseAuthorization();
這裡的順序不能顛倒。第一行是開啟身份驗證,第二行是開啟授權。
第三,配置
JWT需要進行一些簡單的配置來確保安全,至於配置寫在哪裡都可以,我是放在appsettings內:
"JWT": {
"Issuer": "發布者,一般是一個域名",
"Key": "一個新的guid",
"Expires": 600(秒)
}
第四,生成JWT
為了方便大家理解,我這邊直接上程式碼:
public static string GetToken(IOptions<JwtConfig> _options, dynamic customer)
{
var claims = new[] {
new Claim(ClaimTypes.Name,"JWT"),
new Claim("ID",customer.ID),
new Claim("WxOpenID",customer.WxOpenID),
new Claim("Father",customer.Father)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.Key));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _options.Value.Issuer,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(_options.Value.Expires),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
如果在token中想要攜帶某些參數,可以使用Claim進行封裝。
接下來還有3個小步驟:
1、對配置文件中的key進行加密,得到對稱加密key。
2、使用上一步得到的結果生成數字證書。
3、配置token的內容。
最後,就可以生成jwt並且返回了。
第五,獲取JWT內容
正常情況下,JWT除了做驗證以外,還要有一些參數做輔助。上面說了參數傳遞是通過定義claim實現的,那麼怎麼合法的解析呢?還是直接上程式碼:
public static JwtInfo GetInfoFromToken(string token = null)
{
if (token is null)
return null;
string tokenStr = token.Replace("Bearer ", "");
var handler = new JwtSecurityTokenHandler();
var payload = handler.ReadJwtToken(tokenStr).Payload;
var claims = payload.Claims;
JwtInfo info = new JwtInfo()
{
ID = claims.First(claim => claim.Type == "ID")?.Value,
WxOpenID = claims.First(claim => claim.Type == "WxOpenID")?.Value,
Father = claims.First(claim => claim.Type == "Father")?.Value
};
return info;
}
這一段沒什麼好講的,對應的名字拿到對應的參數。不過如果參數不存在這裡會報錯,所以盡量規範一點,首位呼應。
第六,程式碼應用
JWT也生成了,同時也可以反向解析傳遞的參數了,該如何應用到程式碼中去呢?這裡要用到特性。
為需要進行驗證的控制器添加【Authorize】特性,這個控制器下的所有方法在外部調用時就都需要JWT認證才可順利調用,否則返回401(未授權)。如果不是全部方法都需要認證,那麼可以為方法添加【AllowAnonymous】特性來忽略認證限制,如圖:

最後
基於JWT可以延伸出更多玩法,同學們有好的想法歡迎討論。
