0


NET8中WebAPI使用JWT入门教程

目录

1、JWT

现在在各类API的开发中,token已经是必备了。例如:微信公众号开发中,第一个方法就是获取token。JWT具体的定义及组成部分大家可以到网上找找,这儿给一个简单的描述:JWT 令牌是紧凑的 URL 安全令牌,易于在各方之间转移。它们是自包含的,这意味着它们自身内部携带信息,从而减少了对服务器端会话存储的需求。
定义可以从网上找到,但网上入门的例子,要么很简单、要么很复杂,反而不知道如何入门。因此这儿记录一下,在net8的webapi中如何使用JWT的入门教程。

2、具体实现

首先创建

NET8

环境下

WebApi

的项目,通过

nuget

引用包

Microsoft.AspNetCore.Authentication.JwtBearer

appsettings.json

中添加配置信息

{"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}},"AllowedHosts":"*",/**JWT的配置信息,这几个信息都是测试数据,需要根据实际业务自行调整**/"JwtSettings":{"SecretKey":"bAafd@A7d9#@F4*V!LHZs#ebKQrkE6pad2f3kj34c3dXy@",/**存放加密的秘钥**/"Issuer":"ZhengLinTest",/**存放发布者信息**/"Audience":"AllUseAPI",/**存放受众者信息**/"AccessTokenExpirationMinutes":30,"RefreshTokenExpirationDays":7}}

为了能够将配置文件中

JwtSettings

强转换为一个类,需要提前定义一个Model类。

namespaceJWTWebApplication.Models{/// <summary>/// 这个类主要是用于解析appsettings.json里的配置信息,也可以使用其他方式,获取及保存配置信息/// </summary>publicclassJwtSettings{publicstring SecretKey {get;set;}publicstring Issuer {get;set;}publicstring Audience {get;set;}publicint AccessTokenExpirationMinutes {get;set;}publicint RefreshTokenExpirationDays {get;set;}}}

JWT是一加密的符合JSON格式的字符串,那我们就需要定义,到底要加密哪些信息。在本例中我们会加密:姓名、密码、角色、邮箱等信息。因此我们创建一个

,用于自定义需要加密到JWT中的信息。具体的Model如下

namespaceJWTWebApplication.Models{/// <summary>/// 用于存储到token中的数据/// </summary>publicclassUser{publicint Id {get;set;}publicstring Username {get;set;}publicstring Name {get;set;}publicstring Email {get;set;}publicstring Password {get;set;}publicstring[] Roles {get;set;}}}

下面我们会创建一个用于生成

JWT

Service

类,并添加一个生成

jwt

的方法

Crete
namespaceJWTWebApplication.Services{publicclassAuthService{//通过依赖注入的方式,将配置参数带入到类中。后面会在program.cs文件中,进行注册。privatereadonlyJwtSettings _jwtSettings;publicAuthService(IOptions<JwtSettings> jwtSettings){
                _jwtSettings = jwtSettings.Value;}/// <summary>/// 用于令牌的生成/// </summary>/// <param name="user"></param>/// <returns></returns>publicstringCreate(User user){}}}

Create

方法中,先实例化

JwtSecurityTokenHandler

,它负责生成

token

(令牌)

var handler =newJwtSecurityTokenHandler();

下一步是生成令牌的信息并进行签名,因此我们需要刚才配置信息的秘钥,并使用

SigningCredentials

完成签名,

SigningCredentials

需要两个参数:秘钥和算法

var privateKey = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);var credentials =newSigningCredentials(newSymmetricSecurityKey(privateKey),
            SecurityAlgorithms.HmacSha256);

下一步,就是将我们需要加密到

token

中的数据,通过方法实现。该如何添加呢?它的代码是这样的:

newClaim(ClaimTypes.Name, user.Username)//可以理解为键/值结构

为了简化操作,我将创建一个方法来返回我们将保存在令牌中的 ClaimsIdentity(所有令牌声明的列表),该方法会自动添加到令牌的有效负载中。

//准备给Token中的值privatestaticClaimsIdentityGenerateClaims(User user){var ci =newClaimsIdentity();

    ci.AddClaim(newClaim("id", user.Id.ToString()));
    ci.AddClaim(newClaim(ClaimTypes.Name, user.Username));
    ci.AddClaim(newClaim(ClaimTypes.GivenName, user.Name));
    ci.AddClaim(newClaim(ClaimTypes.Email, user.Email));foreach(var role in user.Roles)
        ci.AddClaim(newClaim(ClaimTypes.Role, role));return ci;}

下一步操作是创建 SecurityTokenDescriptor 的实例,以便在令牌中包含基本信息

var tokenDescriptor =newSecurityTokenDescriptor{
    SigningCredentials = credentials,
    Expires = DateTime.UtcNow.AddMinutes(_jwtSettings.AccessTokenExpirationMinutes),
    Subject =GenerateClaims(user)};

然后我使用

handler.CreateToken()

方法生成令牌,并且使用

handler.WriteToken(token)

方法,将

JwtSecurityToken

序列化为紧凑序列化格式

JWT

并返回。

var token = handler.CreateToken(tokenDescriptor);return handler.WriteToken(token);

最终,生成完成的代码如下:

usingJWTWebApplication.Models;usingMicrosoft.Extensions.Configuration;usingMicrosoft.Extensions.Options;usingMicrosoft.IdentityModel.Tokens;usingSystem.IdentityModel.Tokens.Jwt;usingSystem.Security.Claims;usingSystem.Text;namespaceJWTWebApplication.Services{publicclassAuthService{//通过依赖注入的方式,将配置参数带入到类中privatereadonlyJwtSettings _jwtSettings;publicAuthService(IOptions<JwtSettings> jwtSettings){
            _jwtSettings = jwtSettings.Value;}/// <summary>/// 用于令牌的生成/// </summary>/// <param name="user"></param>/// <returns></returns>publicstringCreate(User user){var handler =newJwtSecurityTokenHandler();var privateKey = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);var credentials =newSigningCredentials(newSymmetricSecurityKey(privateKey),
                        SecurityAlgorithms.HmacSha256);var tokenDescriptor =newSecurityTokenDescriptor{
                SigningCredentials = credentials,
                Expires = DateTime.UtcNow.AddMinutes(_jwtSettings.AccessTokenExpirationMinutes),
                Subject =GenerateClaims(user)};var token = handler.CreateToken(tokenDescriptor);return handler.WriteToken(token);}//准备给Token中的值privatestaticClaimsIdentityGenerateClaims(User user){var ci =newClaimsIdentity();

            ci.AddClaim(newClaim("id", user.Id.ToString()));
            ci.AddClaim(newClaim(ClaimTypes.Name, user.Username));
            ci.AddClaim(newClaim(ClaimTypes.GivenName, user.Name));
            ci.AddClaim(newClaim(ClaimTypes.Email, user.Email));foreach(var role in user.Roles)
                ci.AddClaim(newClaim(ClaimTypes.Role, role));return ci;}}}

有了生成token的方法,那我们就需要进行配置,准备使用了。具体来说,就是在

program.cs

中进行配置
首先添加开启授权和认证功能的代码

builder.Services.AddAuthentication();//启用身份验证功能--认证主要是指,用户米、密码是否正确
builder.Services.AddAuthorization();//启用授权功能---授权主要是看有没有权限

app.UseAuthentication();//启用认证功能
app.UseAuthorization();//启用授权功能

其次,要指定使用 JWT 进行身份验证,需要进行配置调整。这涉及设置

DefaultChallengeScheme

以定义如何检查每个传入请求以确定适当的身份验证方法。这可确保应用程序收到的每个请求都被视为 JWT 身份验证

builder.Services.AddAuthentication(x =>{  
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;  
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;});

此外,可以通过

AddJwtBearer()

方法进行验证令牌。在本例中,将使用私钥,并且为了简单起见,排除了对颁发者和受众的验证

//收到的每个请求都被视为 JWT 身份验证
builder.Services.AddAuthentication(x =>{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(x =>{
    x.TokenValidationParameters =newMicrosoft.IdentityModel.Tokens.TokenValidationParameters{
        ValidateIssuer =false,
        ValidateAudience =false,
        IssuerSigningKey =newSymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))};});

因为有些类,用到了依赖注入的方式实现,因此在配置文件中加了一下依赖注入的声明

//依赖注入
builder.Services.AddTransient<AuthService>();
builder.Services.AddOptions();
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));

因此,完成的配置文件如下:

usingJWTWebApplication.Models;usingJWTWebApplication.Services;usingMicrosoft.AspNetCore.Authentication.JwtBearer;usingMicrosoft.Extensions.Configuration;usingMicrosoft.IdentityModel.Tokens;usingMicrosoft.Extensions.Options;usingSystem.Text;var builder = WebApplication.CreateBuilder(args);// Add services to the container.

builder.Services.AddControllers();// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();//依赖注入
builder.Services.AddTransient<AuthService>();
builder.Services.AddOptions();
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));//启用功能
builder.Services.AddAuthentication();//启用身份验证功能--认证主要是指,用户米、密码是否正确
builder.Services.AddAuthorization();//启用授权功能---授权主要是看有没有权限//读取配置文件的数据//这儿自定义了一个JwtSettings类,类里面的属性要与配置文件中的一致var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>();//收到的每个请求都被视为 JWT 身份验证
builder.Services.AddAuthentication(x =>{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(x =>{
    x.TokenValidationParameters =newMicrosoft.IdentityModel.Tokens.TokenValidationParameters{
        ValidateIssuer =false,
        ValidateAudience =false,
        IssuerSigningKey =newSymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))};});//声明一个指定名称的认证策略
builder.Services.AddAuthorization(x =>{
    x.AddPolicy("rolePolicy", p => p.RequireRole("developer"));});var app = builder.Build();// Configure the HTTP request pipeline.if(app.Environment.IsDevelopment()){
    app.UseSwagger();
    app.UseSwaggerUI();}

app.UseAuthentication();//启用认证功能
app.UseAuthorization();//启用授权功能

app.MapControllers();

app.Run();

至此,基本的配置已经完成,让我们开始使用吧
首先,先创建一个api的

Controller

,并写下如下的代码

namespaceJWTWebApplication.Controllers{[Route("api/[controller]/[action]")][ApiController]publicclassJWTTestController:ControllerBase{//依赖注入。在program文件中的依赖注入,这儿就用到了privatereadonlyAuthService _authService;publicJWTTestController(AuthService authService){
                _authService = authService;}//具体的三个方法实现}}

在类里面,我们将会创建三个方法:

Login

test

roletest

。这三个方法分别用于:根据传入的用户米/密码,生成

token

test

roletest

分别用于测试权限认证和测试指定认证名称(就是在

program

中的

x.AddPolicy("rolePolicy", p => p.RequireRole("developer"));

),完整的代码如下:

namespaceJWTWebApplication.Controllers{[Route("api/[controller]/[action]")][ApiController]publicclassJWTTestController:ControllerBase{//依赖注入privatereadonlyAuthService _authService;publicJWTTestController(AuthService authService){
            _authService = authService;}[HttpGet]publicstringLogin(string username,string password){//获取前台传过来的用户名、密码的数据var user =newUser();
            user.Username = username;
            user.Password = password;//从后台进行身份验证,并获取该登录人的其他信息(例如,角色、邮箱等各类信息)
            user.Name ="zhenglin";
            user.Id =1;
            user.Email ="[email protected]";
            user.Roles =newstring[]{"developer"};//返回tokenreturn _authService.Create(user);}[Authorize][HttpGet]publicStatusCodeResulttest(){returnStatusCode(200);}[Authorize("rolePolicy")][HttpGet]publicStatusCodeResultroletest(){returnStatusCode(200);}}}

至此,全部代码完成,准备验证
首先测试一下

Login

,看能否返回

token

在这里插入图片描述其次,测试一下携带

token

test

方法
在这里插入图片描述
最后测试一下,指定名称的认证
在这里插入图片描述

3、代码下载

代码下载:下载地址

标签: JWT NET8 WebAPI

本文转载自: https://blog.csdn.net/zlbcdn/article/details/141034707
版权归原作者 zlbcdn 所有, 如有侵权,请联系我们删除。

“NET8中WebAPI使用JWT入门教程”的评论:

还没有评论