前言
在網上走一朝JWT,都會拿來和Session對比,這里不細說理論了,大家伙們百度找找,很多,很詳細;這里我們直接實操JWT在Asp.NetCore3.1中的應用;
走起
1. 建一個WebAPI項目(之前都截圖好多了,這里不截圖了);
2. Nuget包中安裝對應組件

3. 在Startup.cs文件中進行配置
ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//獲取配置文件信息,因為是共用的,所以就統一放配置文件了
string secret = Configuration.GetValue<string>("JWT:Secrete");//秘鑰,這里的秘鑰長度不低於16
string issuer_z = Configuration.GetValue<string>("JWT:Issuer");//頒發方
string audience_z = Configuration.GetValue<string>("JWT:Audience");//接收方
//開始配置JWT
services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
//是否驗證秘鑰
ValidateIssuerSigningKey = true,
//秘鑰,記住一定要大於等於16位
IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
//是否驗證頒發者
ValidateIssuer=true,
//頒發者
ValidIssuer= issuer_z,
//是否驗證接收方
ValidateAudience=true,
ValidAudience= audience_z,
//必須要有超時時間
RequireExpirationTime=true,
//是否驗證超時,當設置exp和nbf時有效,同時啟用ClockSkew
ValidateLifetime=true,
//這是一個緩沖時間,系統默認是5分鍾,可設置;則Token有效時間就是過期時間+這個設置的緩沖時間
ClockSkew=TimeSpan.FromSeconds(50)
};
});
}
Configure方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
4. 在對應Controller上或Action上加上Authorize標記

經過以上四步,基本上就用JWT對API進行認證保護,不信試一下,程序運行起來,Postman走起:
其他接口沒加Authorize特性的,正常訪問,如下:

加了特性的Action,訪問返回401,如下:

也就是說,加了Authorize特性的Action需要進行認證才能進行訪問;換句話來說,請求來的信息,需要服務端能解析驗證,JWT通過Token實現的;
生成Token
在UserController下增加一個獲取Token的方法,如下:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace JwtDemo.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IConfiguration _configuration;
public UserController(IConfiguration configuration)
{
_configuration = configuration;
}
[Authorize]
public IActionResult UserInfo()
{
return Ok(new { Name = "Zoe", Age = 18 });
}
[HttpPost]
public IActionResult GetToken(User u)
{
if(u==null||string.IsNullOrEmpty(u.LoginName)||string.IsNullOrEmpty(u.LoginPwd))
{
return Ok(new { code=-1,msg="用戶名或密碼不能為空"});
}
//驗證用戶
if(u.LoginName!="Zoe"&&u.LoginPwd!="admin")
{
return Ok(new { code = -1, msg = "用戶名或密碼錯誤" });
}
//驗證成功,構建Token
string strToken = GenerateToken(u);
//返回信息
return Ok(new {code=1,msg="Success",data=new { LoginName=u.LoginName,Token=strToken,Expire=3600,TokenType=JwtBearerDefaults.AuthenticationScheme } });
}
private string GenerateToken(User u)
{
//這里也是從配置文件讀取的,和上面讀取的一致,否則開啟對應驗證的話會不通過
string secret = _configuration.GetValue<string>("JWT:Secrete");
string issuer_z = _configuration.GetValue<string>("JWT:Issuer");
string audience_z = _configuration.GetValue<string>("JWT:Audience");
//指定加密算法
var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256);
//可以在Token里增加信息,但這里不要加私密信息,比如密碼等這種數據
var claims = new Claim[] { new Claim("UserName", u.LoginName) };
//組裝數據
SecurityToken securityToken = new JwtSecurityToken(
issuer: issuer_z,//頒發者
audience: audience_z,//接收者
signingCredentials: securityKey,//組裝的秘鑰
expires:DateTime.Now.AddHours(1),//有效時間
claims: claims
);
//生成Token
return new JwtSecurityTokenHandler().WriteToken(securityToken);
}
}
public class User
{
public string LoginName{ get; set; }
public string LoginPwd{ get; set; }
}
}
這樣Token就搞定了,項目運行起來,Postman訪問一下:

這樣我們就可以拿着這個Token進行保護API訪問了,前提是在有效期之內,生成的Token可以在JWT.io官網進行解析,如下:

Token在Postman中使用,把生成的Token靠到Token的位置,訪問保護的API,如下可以訪問了:

其實本質就是在請求頭Authorization中加上"Bearer 生成的Token",中間一定要有空格;前度調用的話也是在請求頭中添加就行;

總結
JWT使用是不是很簡單,輕松實現API的認證保護;下一遍我們說說JWT的權限驗證;
關注公眾號,每周更新至少兩篇關於.NetCore相關文章

