开发随笔记录——关于JWT(身份令牌效验)的有关内容。

声明:本次记录仅供参考,若设计到利益等问题,请联系博主进行删帖。

接下来,开始我的独白。博主在开发过程中也是遇到了很多关于JWT的问题,也是参考了很多前辈的经验也参考了官网的说明文档,要是有什么理解不对的地方还请各路大神指点一二。好了,我们步入主题。

以下内容皆是在官网copy下来,不想看这些啰嗦话的同志可以直接看主体内容。

什么是 JWT?

  所谓的JWT也就是叫做JSON Web Token。那么JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息。该信息可以被验证和信任,因为它是经过数字签名的。JWT 可以使用秘密(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名

什么是时候使用JWT?

以下是 JSON Web Tokens 有用的一些场景:

  • 授权:这是使用 JWT 最常见的场景。用户登录后,每个后续请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小,并且能够轻松跨不同域使用。

  • 信息交换:JSON Web Tokens 是一种在各方之间安全传输信息的好方法。因为 JWT 可以被签名——例如,使用公钥/私钥对——你可以确定发件人就是他们所说的那样。此外,由于使用标头和有效负载计算签名,因此您还可以验证内容是否未被篡改

什么是 JWT 结构?

在其紧凑形式中,JSON Web Tokens 由用点 ( .)分隔的三个部分组成,它们是:

  • 标题
  • 有效载荷
  • 签名

因此,JWT 通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

标题

标头通常由两部分组成:令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA。

例如:{ "alg": "HS256", "typ": "JWT" }

然后,这个 JSON 被Base64Url编码以形成 JWT 的第一部分。

有效载荷

令牌的第二部分是负载,其中包含声明。声明是关于实体(通常是用户)和附加数据的声明。共有三种类型的声明:注册声明公共声明私人声明。

  • 注册声明:这些是一组预定义的声明,这些声明不是强制性的,而是推荐的,以提供一组有用的、可互操作的声明。其中一些是: iss(发行者)、 exp(到期时间)、 sub(主题)、 aud(受众)等等(想去了解的同志可以进去仔细研究研究)
  • 公共声明:这些可以由使用 JWT 的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web Token Registry中定义或定义为包含抗冲突命名空间的 URI。
  • 私人声明:这些都是使用它们同意并既不是当事人之间建立共享信息的自定义声明注册公众的权利要求。

一个示例有效载荷可能是:{ "sub": "1234567890", "name": "John Doe", "admin": true }

然后对有效负载进行Base64Url编码以形成 JSON Web 令牌的第二部分。

 

签名

要创建签名部分,您必须获取编码的标头、编码的有效载荷、秘密、标头中指定的算法,并对其进行签名。

例如,如果要使用 HMAC SHA256 算法,则签名将通过以下方式创建:HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

签名用于验证消息在此过程中没有更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者是它所说的那个人。

标题+有效载荷+签名

------------------------------------------------------------------------------主体内容--------------------------------------------------------------------------------

本次开发使用ASP.NET Core,开发前应先在NuGet程序包管理器中下载Microsoft.AspNetCore.Authentication.JwtBearer(博主使用的是5.0.8版本)

 

安装完毕后就可以代码中使用了,首先要在API对应的controller上引用该程序包:using Microsoft.AspNetCore.Authentication.JwtBearer;

在对应API(博主使用登录API)中使用写入以下代码

复制代码
//创建jwt
//header
var signingAlgorithm = SecurityAlgorithms.HmacSha256;
//payload
//token数据 //自定义数据 var claims = new[] { new Claim("userId","123456") }; //signiture var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecurityKey"]);//自己的私钥信息 var signingkey = new SymmetricSecurityKey(secretByte); var signingCredentials = new SigningCredentials(signingkey, signingAlgorithm); var token = new JwtSecurityToken( issuer: _configuration["Authentication:Issure"], //发布者 audience: _configuration["Authentication:Audience"], //接受者 claims,//该token内储存的自定义字段信息 notBefore:DateTime.UtcNow,//token签发时间 expires:DateTime.UtcNow.AddDays(1),//token过期时间 signingCredentials//用于签发token的秘钥算法 );
string TokenStr = new JwtSecurityTokenHandler().WriteToken(token);
复制代码

 若在API中加入授权认证,就要在Startup.cs文件中添加如下代码:

复制代码
      public void ConfigureServices(IServiceCollection services)
      {
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option => {

                var secretByte = Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]);
                option.TokenValidationParameters = new TokenValidationParameters() {
                    // 验证发布者
                    ValidateIssuer = true,
                    // 读配置Issure
                    ValidIssuer = Configuration["Authentication:Issure"],
                    // 验证接收者
                    ValidateAudience = true,
                    // 读配置Audience
                    ValidAudience = Configuration["Authentication:Audience"],

                    // 验证过期时间
                    ValidateLifetime = true,

                    // 设置生成token的秘钥
                    IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                };    
            });
      }
复制代码

appsettings.json配置信息如下:

这样API每次的请求都会验证header中带的Authorization参数是否符合JWT的验证规范。

众所周知,在Swaager兴起的时代,它同样可以具备验证JWT的功能,只需要在安装好正常使用Swaager的基础上,在Startup.cs文件中添加如下代码:

复制代码
    services.AddSwaggerGen(options => {
                var securityScheme = new OpenApiSecurityScheme()
                {
                    Description = "JWT认证授权,使用直接在下框中输入Bearer {token}(注意两者之间是一个空格)",
                    Name = "Authorization",//JWT默认参数名称                   
                    In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头)
                    //使用Authorize头部
                    Type = SecuritySchemeType.Http,//使用ApiKey在调试时需要将Bearer {token}全部加入value;使用Http在调试时只需要把token值加入value即可。
                    //内容为以 bearer开头
                    Scheme = "bearer",
                    BearerFormat = "JWT"//header头部bearer信息格式转化为JWT
                };

                //把所有方法配置为增加bearer头部信息
                var securityRequirement = new OpenApiSecurityRequirement
                {
                    {
                      new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference
                          {
                              Type = ReferenceType.SecurityScheme,
                              Id = "bearerAuth"
                          }
                      },
                      new string[] {}
                    }
                };
                //注册到swagger中
                options.AddSecurityDefinition("bearerAuth", securityScheme);
                options.AddSecurityRequirement(securityRequirement);
            });
复制代码

这样就可以在Swaager中愉快的使用JWT验证了。

posted @   苏瑾~  阅读(191)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示