JWT网站:https://jwt.io/
JWT基础内容:https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=pc
在.Net Core中接入WebApi可用于确保WebApi的安全。
创建空Web项目
dotnet new web -o JWTDemo
Nuget安装
dotnet add package System.IdentityModel.Tokens.Jwt
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
创建Const.cs类,没什么特别的,只是常量存储配置字段。
public class Const
{
public const string Issuer = "Alex";
public const string Audience = "Alex";
public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";
}
根目录下创建Controllers文件夹,继续创建AuthController控制器类。
修改控制器路由
[Route("api/[controller]/[action]")]
创建Login方法
public async Task<IActionResult> Login(LoginInputDto input)
{
//简单的账号密码对比
if ("Alex".Equals(input.Account) && "123456".Equals(input.Password))
{
//Claim可以理解为是Token的属性
var claims = new[] {
//生效时间
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
//生命周期时间
new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now).AddSeconds(60).ToUnixTimeSeconds()}"),
//发行人
new Claim(JwtRegisteredClaimNames.Iss,Const.Issuer),
//接收人
new Claim(JwtRegisteredClaimNames.Aud,Const.Audience)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey));
var crdes = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
signingCredentials: crdes,
claims: claims
);
return await Task.FromResult(
Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) })
);
}
else
{
return await Task.FromResult(
BadRequest(new { msg="账号或者密码错误"})
); ;
}
}
修改Startup.cs文件
修改 ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options=> {
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = Const.Issuer,
ClockSkew = TimeSpan.FromSeconds(30),
ValidAudience = Const.Audience,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey))
};
});
services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
}
修改Configure方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapGet("/", async context =>
//{
// await context.Response.WriteAsync("Hello World!");
//});
endpoints.MapControllerRoute(
name: "default",
pattern: "api/{controller=home}/{action=index}/{id?}"
);
});
}
Postman访问正常获取Token
image-20200607160405586.png可以创建一个ResourceController 控制器类,分别创建两个方法,其中一个标记[Authorize] 特性
public class ResourceController : ControllerBase
{
[Authorize]
[HttpGet]
public async Task<string> GetResourceWithAuth()
{
return await Task.FromResult("GetResourceWithAuth");
}
[HttpGet]
public async Task<string> GetResourceWithoutAuth()
{
return await Task.FromResult("GetResourceWithoutAuth");
}
}
Postman携带Token进行访问,访问正常。
image-20200607161527481.png60s后可以再次进行访问(tokens生成时,expire为60s),token失效,访问失效。
image-20200607161638134.png
网友评论