對於 登陸,身份,授權這之類的操作,我們最常用的幾種方法無非就是 cookie session token
這三者的差別
https://www.cnblogs.com/moyand/p/9047978.html
這篇文章寫的非常好
cookie和session到了微服務和負載均衡需要擴展時,就顯得力不從心,而token這種無狀態的身份驗證就更加適合
JWT
所謂JWT就是 JSON WEB Token 是一種基於JSON的、用於在網絡上聲明某種主張的令牌(token)。JWT通常由三部分組成:頭信息(header),消息體(payload)和簽名(signature)。
頭信心中會生命算法類型:
header = '{"alg":"HS256","typ":"JWT"}'
消息體:
payload = '{"loggedInAs":"admin","iat":1422779638}'//iat表示令牌生成的時間
只有簽名是加密的,但是你真實中看到的token樣子是長這樣
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxIiwiVXNlck5hbWUiOiJhZG1pbnMiLCJpYXQiOiIxNTc2MTE3MTY0IiwibmJmIjoiMTU3NjExNzE2NCIsImV4cCI6MTU3NjExNzg4NCwiaXNzIjoiRnl0U29hIiwiYXVkIjpbIkNtcyIsIkNtcyJdLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbnMifQ.1HFSPephhGAUqwl0zRvTvd-ow7_6E_S78DGvaiY_UnQ
一眼看上去好像都被加密了,但其實上header和payload只是進行了base64的編碼,仔細的話你可以發現token里面有兩個點“.”,進行分隔
認證與授權
首先我們要弄清楚認證(Authentication)和授權(Authorization)的區別,以免混淆了。認證是確認的過程中你是誰,而授權圍繞是你被允許做什么,即權限。顯然,在確認允許用戶做什么之前,你需要知道他們是誰,因此,在需要授權時,還必須以某種方式對用戶進行身份驗證。
開始代碼
首先,我寫了一個JWTapi的.netcore3.0作為授權服務,一個TestApi2作為業務api
首先看JWTapi
僅僅需要一個誰都能訪問的接口,提供登陸服務,(查詢登陸結果那個地方,應該做數據庫的匹配,我節省時間寫了個假的)
生成token的方法中要設置Issuer,Audience,JWTSecretKey,這三者要與認證服務中的相同才能解開
接下來來看Testapi2
Testapi2作為一個業務api,作為一個被訪問者,不是誰都能見我的,你要到達某個級別,才能見到我,所以要對來訪的人進行認證
所以要在ConfigureServices中,添加
services.AddAuthentication()
.AddJwtBearer(JwtAuthorizeAttribute.JwtAuthenticationScheme, o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否驗證Issuer
ValidateAudience = true,//是否驗證Audience
ValidateIssuerSigningKey = true,//是否驗證SecurityKey
ValidateLifetime = true,//是否驗證超時 當設置exp和nbf時有效 同時啟用ClockSkew
ClockSkew = TimeSpan.FromSeconds(30),//注意這是緩沖過期時間,總的有效時間等於這個時間加上jwt的過期時間,如果不配置,默認是5分鍾
ValidAudience = Configuration["JwtAuth:Audience"],//Audience
ValidIssuer = Configuration["JwtAuth:Issuer"],//Issuer,這兩項和前面簽發jwt的設置一致
RequireExpirationTime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtAuth:SecurityKey"]))//拿到SecurityKey
};
o.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
// 如果過期,則把<是否過期>添加到,返回頭信息中
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
這里面的Issuer,Audience,SecurityKey這三者,要與生成token時使用的一樣
然后找一個controller,加上某種角色才可以訪問的限制
使用postman模擬登陸
會得到一串token值,將這串token放入postman,選擇Testapi2中的api進行發送
可以發送,獲得200的返回值,如果token寫錯了,就會得到

401的返回值
注意,認證中的規則只會在網站第一次訪問時跑一次,也就是AddJwtBearer中的代碼只會在網站第一次訪問時跑一次,如果你的加密Audience,Issuer,SecurityKey變了,也需要重新啟動一次網站
本例子gitee地址
https://gitee.com/hallejuyahaha/OcelotDemo-Dotnet2.2