首页 > 其他分享 >使用JWT

使用JWT

时间:2023-01-22 10:11:26浏览次数:39  
标签:claims string JWT public 使用 var new payload

JWT用来验证访问者身份,需要以下内容:

1、一个密钥,32位,越复杂越好,我用两个GUID去掉-后拼在一起。

2、一个json格式的配置文件,里面保存密钥和过期时间。

"JWTSetting": {
    "SecKey": "41492fbc0bd046fe8c8562657897b268b9201e4afbbf46e0b08f09051ff286144",
    "Expires": 1
  },

  

3、一个payload段的对象模型,用来生成JWT的payload段数据,还可以用来还原对象。

 

    /// <summary>
    /// 配合JWTHelper中的Claim,属性全部用小写,与系统自带的统一。
    /// </summary>
    public class JwtPayloadModel
    {
        public string nameidentifier { get; set; } =string.Empty;
        public string name { get; set; } = string.Empty;
        public List<string> roles { get; set; } = new List<string>();
        public string passport { get; set; } = string.Empty;

        public string exp { get; set; }=string.Empty;
        /// <summary>
        /// 版本号,为了实现token过期的自增数,可以放到数据库或redis中,每次登录后自增。
        /// 调用接口时对比版本号大小,判断是否过期,过期则提示token过期需要重新登录。
        /// (实际上用户token并未过期,只是为了实现多点登录唯一做出的变通)
        /// </summary>
        public long version { get; set; }
    }

  

4、一个生成JWT的函数,需要用到密钥、payload段数据和过期时间。

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="expiresHour">到期时间(小时)</param>
        /// <param name="payload">payload</param>
        /// <returns></returns>
        public static string Encryption(string key, JwtPayloadModel payload, int expiresHour = 24)
        {

            var claims = new List<Claim>();

            claims.Add(new Claim(ClaimTypes.NameIdentifier, payload.nameidentifier));
            claims.Add(new Claim(ClaimTypes.Name, payload.name));
            for (int i = 0; i < payload.roles.Count; i++)
            {
                claims.Add(new Claim(ClaimTypes.Role, payload.roles[i]));
            }
            claims.Add(new Claim("passport", payload.passport));
            claims.Add(new Claim("version", payload.version.ToString()));
            /*
            claims.Add(new Claim(ClaimTypes.NameIdentifier, "1"));
            claims.Add(new Claim(ClaimTypes.Name, "root"));
            claims.Add(new Claim(ClaimTypes.Role, "Admin"));*/



            DateTime expires = DateTime.Now.AddHours(expiresHour);
            byte[] secBytes = Encoding.UTF8.GetBytes(key);
            var secKey = new SymmetricSecurityKey(secBytes);
            var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
            var tokenDescriptor = new JwtSecurityToken(claims: claims,
                expires: expires, signingCredentials: credentials);
            string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
            return jwt;
        }

  

5、Program中增加JWT验证代码。

//配置jwt验证
void ConfigureJWT()
{
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
    var jwtOpt = builder.Configuration.GetSection("JWTSetting").Get<TDAuth.JWTSetting>();
    byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt?.SecKey ?? "");
    var secKey = new SymmetricSecurityKey(keyBytes);
    x.TokenValidationParameters = new()
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = secKey
    };
    //增加对SignalR调用者的身份验证
    x.Events = new JwtBearerEvents {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];
            var path = context.HttpContext.Request.Path;
            if(!string.IsNullOrEmpty(accessToken)
            &&path.StartsWithSegments("/Hubs/Demo"))
            {
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        }
    };
});
}

6、在需要验证的代码段前加[Authorize]标记。

/// <summary>
        /// jwt还原
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("/ReductionJWT")]
        [Authorize]
        public ActionResult ReJWT(string jwt)
        {
            string key = _jwtSetting.Value.SecKey ?? "12345678901234567890";
            TDAuth.JwtPayloadModel model = TDAuth.JWTHelper.Decode(key, jwt);

            return Ok(model);
        }

7、配置Swagger支持输入JWT

//配置swagger
void ConfigureSwagger()
{
    builder.Services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo
        {
            Version = "v1",
            Title = "API标题",
            Description = "API描述"
        });
        var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
    });
    builder.Services.AddSwaggerGen(c =>
    {
        var scheme = new OpenApiSecurityScheme()
        {
            Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "Authorization"
            },
            Scheme = "oauth2",
            Name = "Authorization",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.ApiKey,
        };
        c.AddSecurityDefinition("Authorization", scheme);
        var requirement = new OpenApiSecurityRequirement();
        requirement[scheme] = new List<string>();
        c.AddSecurityRequirement(requirement);
    });
}

  

 

标签:claims,string,JWT,public,使用,var,new,payload
From: https://www.cnblogs.com/tudou365/p/17064289.html

相关文章

  • 使用SignalR实现简单聊天室和推送广告
    所需材料:一个SignalR处理程序、一个前端页面、一个后端推广告服务、配置。1、SignalR继承自Hub,里面有一个群发消息的方法,可以控制访问权限。///<summary>///......
  • C++内存分配方法new与placement new使用方法详解
    tags:C++写在前面总结一下C++内存分配中的​​new​​​/​​delete​​​方法,以及一个很有意思的工具:​​placementnew​​.参考:cppprimer5ed,pp409,pp726(19.1).......
  • 第五十二章 使用 ^SystemPerformance 监视性能 - IBM AIX® 平台的 InterSystems IRIS
    第五十二章使用^SystemPerformance监视性能-IBMAIX®平台的InterSystemsIRIS性能数据报告%SS-使用ALL^%SS命令在运行过程中采集了四个样本。AIXinfo......
  • C++的宏利用include和undef来重复使用
    如dll导出函数,需要定义以及QueryInterface,其中函数有多个,如果想代码尽量简洁,只有这个方法定义#defineNVIDIA_API_DEF(_fun) decltype(_fun) *_##_fun=NUL......
  • 02 Scanner进阶使用
    01用户交互ScannerScanner要导入包:importjava.util.Scanner;从键盘上读取数据//开始时的固定套路:Scannersc1=newScanner(System.in);//中间的关键步骤:String......
  • putty使用教程(总结)
    putty使用教程(总结):https://www.cnblogs.com/yuwentao/archive/2013/01/06/2846953.html最近开始使用putty,在网络上看到一份很不错的教程,共享一下:putty使用方法,中文教程......
  • [ 6--JWT学习 | 青训营笔记]
    这是我参与「第五届青训营」伴学笔记创作活动的第6天JWT介绍JSONWebToken(orJWT)只是一个包含某种意义数据的JSON串。它最重要的特性就是,为了确认它是否有效,我们......
  • 使用Addressables.LoadAssetAsync<Asset>(target)加载unity资源,不止是gameobject
    要声明的方法:publicstaticasyncTask<string>ReadJsonData(stringtarget){  TextAssetjsonDataObject=awaitAddressables.LoadAssetAsync<TextAsset>(target).......
  • 一文解决如何使用 C 语言判断质数(素数)[ 附解析与源码 ]
    前言质数历来都是数学界的宠儿,是数学里神秘的谜团。质数又和C语言有着不解之缘,本篇文章将讲解如何用C语言判断质数。为了方便大家在读完此文章后使用文中程序,我会将......
  • Clion使用
    1.main函数对于一个项目只有一个main函数,如果想运行多个文件的主函数,如下代码注意添加到如下文件下#遍历项目根目录下所有的.cpp文件file(GLOB_RECURSEfiles*.c......