【个人博客搭建】(10)添加JWT

1、JWT:

JWT,即JSON Web Token,是一个开放标准,用于在各方之间安全地传输信息。以下是它的详细介绍:

  • 结构:JWT由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature)。头部通常由两部分组成:令牌的类型(通常为“JWT”)和所使用的签名算法,例如HMAC SHA256或RSA。载荷包含声明(Claims),这些是关于实体(通常是用户)和其他数据的信息。签名是对头部和载荷的加密,确保令牌在传输过程中未被篡改。
  • 用途:JWT主要用于在网络环境中传递安全信息,尤其是在身份验证和授权场景中。它可以作为HTTP请求头的一部分发送,或者嵌入到URL中。由于JWT是自包含的,它可以减少对服务器存储的依赖,因为服务器不需要保留与令牌相关的会话信息。
  • 工作原理:当客户端请求服务时,服务端会验证客户端提供的JWT。如果JWT有效且签名正确,服务端会处理请求。否则,将拒绝服务。这个过程保证了只有持有正确JWT的用户才能访问受保护的资源。
  • 优势:JWT的主要优势在于其简单性和可移植性。它不依赖于服务器端的会话存储,因此可以更容易地实现跨域解决方案。此外,由于JWT是无状态的,它可以减少服务器的内存使用,提高可扩展性。

总的来说,JWT是一种灵活、安全且易于实现的身份验证方法,适用于现代Web应用程序和服务。

使用: 

讯飞星火:

在.NET Core中,使用JWT(JSON Web Tokens)可以为Web API添加身份验证和授权。以下是如何在.NET Core Web API中使用JWT的步骤:

  1. 安装JWT相关的NuGet包:您需要在项目中安装System.IdentityModel.Tokens.Jwt包,以及用于处理JWT的第三方库,如Microsoft.AspNetCore.Authentication.JwtBearer
  2. 配置JWT认证服务:在Startup.cs文件的ConfigureServices方法中,需要添加JWT认证服务,并配置相关的选项,如密钥、算法和过期时间等。
  3. 配置授权策略:在Startup.cs文件的Configure方法中,使用app.UseAuthorization来启用授权中间件,并定义哪些控制器或操作需要JWT认证。
  4. 创建令牌生成和验证方法:创建一个类,用于生成JWT令牌,并在需要的地方调用这个类的方法来生成令牌。同时,需要创建一个方法来验证令牌的有效性。
  5. 用户登录和注册:在用户登录时,验证用户的凭据,如果成功,则生成一个JWT令牌并返回给客户端。客户端在后续的请求中需要在HTTP头部的Authorization字段中携带这个令牌。
  6. 处理令牌过期:在服务器端,需要处理JWT令牌过期的情况。通常,这涉及到捕获特定的异常,并向客户端返回适当的错误信息。
  7. 客户端使用JWT:客户端在接收到JWT令牌后,应该在每次向服务器发送请求时都在HTTP头部的Authorization字段中包含该令牌。
  8. 安全性考虑:确保使用HTTPS来保护JWT令牌在传输过程中的安全,避免令牌被截获。
  9. 日志和监控:为了安全起见,应该记录JWT的生成、验证和使用情况,以便于问题追踪和安全审计。
  10. 测试:在实际部署之前,彻底测试JWT的生成、验证和授权流程,确保没有安全漏洞。
  11. 文档和教育:为开发者和维护人员提供关于如何使用和处理JWT的文档指导,以确保正确和一致的使用。

总的来说,上述步骤是一个基本的指南,具体的实现可能会根据您的项目需求和技术栈有所不同。在使用JWT时,需要考虑到安全性和可维护性,确保系统的整体安全。

我们使用他主要是为了方便控制接口的访问权限,以及登录人信息的获取

2、 安装nuget包:Microsoft.AspNetCore.Authentication.JwtBearer

3、代码

        3.1、配置文件

  /* JWT配置 */
  "JWT": {
    "ValidIssuer": "plateau.poetize.blog.Issuer",
    "ValidAudience": "plateau.poetize.blog.Audience",
    "IssuerSigningKey": "cGxhdGVhdS5wb2V0aXplLmJsb2cud2ViYXBpLmp3dC5Jc3N1ZXJTaWduaW5nS2V5"
  }

        3.2、模型

    /// <summary>
    /// JWT json配置文件模型
    /// </summary>
    public class JwtOptions
    {
        public string ValidIssuer { get; set; }
        public string ValidAudience { get; set; }
        public string IssuerSigningKey { get; set; }
    }

    public class JwtClaim
    {
        public string Id { get; set; }
        public string NickName { get; set; }
        public string Name { get; set; }
        public string UserType { get; set; }
        public string Roles { get; set; }
        public string Menus { get; set; }
    }

        3.3、注入:

#region JWT

var validIssuer = AppSettings.app(new string[] { "JWT", "ValidIssuer" });
var validAudience = AppSettings.app(new string[] { "JWT", "ValidAudience" });
var issuerSigningKey = AppSettings.app(new string[] { "JWT", "IssuerSigningKey" });

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = validIssuer, // 发行者
        ValidAudience = validAudience, // 接收方
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(issuerSigningKey)) // 密钥
    };
});

#endregion

app.UseAuthentication();
app.UseAuthorization();

        3.4、service:

  public class JwtService : IJwtService
  {
      private readonly string _issuer = AppSettings.app(new string[] { "JWT", "ValidIssuer" });
      private readonly string _audience = AppSettings.app(new string[] { "JWT", "ValidAudience" });
      private readonly string _key = AppSettings.app(new string[] { "JWT", "IssuerSigningKey" });

      public JwtService(string issuer, string audience, string secretKey)
      {
          _issuer = issuer;
          _audience = audience;
          _key = secretKey;
      }

      public string GenerateToken(JwtClaim jwtClaim)
      {
          var claims = new[]
          {
              new Claim("Id",jwtClaim.Id),
              new Claim("NickName",jwtClaim.NickName),
              new Claim("Name",jwtClaim.Name),
              new Claim("UserType",jwtClaim.UserType),

              //权限
              new Claim("Roles",jwtClaim.Roles),
              new Claim("Menus",jwtClaim.Menus),
          };

          var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
          var jmType = SecurityAlgorithms.HmacSha256Signature;
          var tokenDescriptor = new SecurityTokenDescriptor
          {
              Subject = new ClaimsIdentity(claims),
              Expires = DateTime.Now.AddMinutes(120), // 设置过期时间(120分钟)
              Issuer = _issuer,
              Audience = _audience,
              SigningCredentials = new SigningCredentials(symmetricSecurityKey, jmType)
          };

          var tokenHandler = new JwtSecurityTokenHandler();
          var token = tokenHandler.CreateToken(tokenDescriptor);
          var result = tokenHandler.WriteToken(token);
          return result;
      }

      public bool ValidateToken(string token)
      {
          var tokenHandler = new JwtSecurityTokenHandler();
          try
          {
              var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
              var parameters = new TokenValidationParameters
              {
                  ValidateIssuerSigningKey = true,
                  IssuerSigningKey = symmetricSecurityKey,
                  ValidateIssuer = true,
                  ValidIssuer = _issuer,
                  ValidateAudience = true,
                  ValidAudience = _audience,
                  ValidateLifetime = true,
                  ClockSkew = TimeSpan.Zero // 严格验证过期时间
              };

              tokenHandler.ValidateToken(token, new TokenValidationParameters(), out SecurityToken validatedToken);
              return validatedToken is JwtSecurityToken jwtToken && jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature);
          }
          catch (Exception)
          {
              return false;
          }
      }
  }

        3.5、测试:Controller层


    /// <summary>
    /// Jwt 控制器
    /// </summary>
    [ApiVersionCustomRoute(SwaggerDocSettings.ApiVersions.v1)]
    [ApiController]
    public class JwtController : ControllerBase
    {
        private readonly IJwtService _iJwtService;
        private readonly ILogger<JwtController> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="iJwtService"></param>
        /// <param name="logger"></param>
        public JwtController(IJwtService iJwtService, ILogger<JwtController> logger)
        {
            _iJwtService = iJwtService;
            _logger = logger;
        }

        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="jwtClaim">jwtClaim模型(构造Claim)</param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult GenerateToken(JwtClaim jwtClaim)
        {
            var token = _iJwtService.GenerateToken(jwtClaim);
            return ApiResultHelper.Success(token);
        }

        /// <summary>
        /// 验证Token
        /// </summary>
        /// <param name="token">token</param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult ValidateToken(string token)
        {
            var bl = _iJwtService.ValidateToken(token);
            return ApiResultHelper.Success(bl);
        }

        /// <summary>
        /// 测试权限
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Authorize]
        public string Test()
        {
            return "ok!";
        }


    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558112.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何构建企业技术架构-解决内部系统连接的问题

随着企业信息化建设的深入&#xff0c;各类管理系统在运营管理中发挥着关键作用。为了实现数据共享、业务流程自动化和决策支持的无缝对接&#xff0c;往往搭建一个高效协同的技术架构至关重要。本文将以人事系统、泛微OA&#xff08;Office Automation&#xff09;及ERP&#…

基于Springboot+Vue的Java项目-网上点餐系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

【御控物联】Java JSON结构转换(4):对象To对象——规则属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON对象 To JSON对象》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

Nginx莫名奇妙返回了404

描述 nginx作为反向代理&#xff0c;代理python的服务&#xff0c;但是通过代理访问服务的时候&#xff0c;报了404的错误。 难受的是客户现场没有查看日志的权限&#xff0c;只有查看配置文件的权限&#xff0c;我们检测了几遍配置文件也没有找到问题&#xff0c;哎~ 问题引…

Python兼职:只需要一台电脑宅在家,轻松实现月入过万!

Python兼职副业 Python是一种简单易学、高效强大的编程语言&#xff0c;正变成越来越多人选择的热门技能。不论你是否有编程基础&#xff0c;在学习Python的道路上&#xff0c;坚持每天投入2小时&#xff0c;你将看到巨大的回报。 学习Python不仅可以为你提供更多就业机会&am…

【情侣博客网站】

效果图 PC端 建塔教程 第一步&#xff1a;下载网站源码&#xff08;在文章下方有下载链接&#xff09; 第二步&#xff1a;上传到服务器或虚拟主机&#xff0c;解压。 第三步&#xff1a;这一步很关键&#xff0c;数据库进行连接&#xff0c;看图 admin/connect.php就是这…

链表带环问题——leetcode环形链表1 2

证明链表带环 链表的带环问题指的是本该指向NULL的最后一个节点指向了之前的节点&#xff0c;导致链表成环&#xff0c;找不到尾结点的情况&#xff0c;那么我们该如何证明链表带环呢&#xff1f; 我们可以类比物理中的追及问题&#xff0c;让快慢指针同时走&#xff0c;两者相…

element-ui form表单自定义label的样式、内容

element-ui form表单自定义label的样式、内容 效果截图 代码 <el-form size"small" :inline"true" label-width"120px"><el-form-item prop"name"><div slot"label"><i style"color: red;"…

步步精科技获得发明型专利,提升Type-C连接器行业竞争力

在电子科技日新月异的时代&#xff0c;连接器作为电子设备中不可或缺的一部分&#xff0c;其安全性、稳定性和性能水平直接关系到设备的使用效果和用户体验。深圳市步步精科技有限公司&#xff08;以下简称“步步精科技”&#xff09;一直致力于连接器领域的技术创新和产品研发…

盒子模型之弹性盒模型

经常适用于手机端图标布局 display: flex;让这个盒子显示成弹性盒&#xff08;很适合移动端布局&#xff09; 影响&#xff1a;1.让里面的子元素默认横向排列 2.如果子元素是行内元素&#xff0c;则直接变成块元素 3.只有一个元素&#xff0c;margin: auto;自动居中 <!DOCT…

学习Python先从了解Python开始

Python是一种高级编程语言&#xff0c;它的语法简洁易读&#xff0c;功能强大&#xff0c;应用领域广泛。Python不仅适用于数据科学、机器学习、Web开发等领域&#xff0c;还可以用于自动化脚本编写、游戏开发等。在本文中&#xff0c;我们将探讨Python的特点、应用领域以及未来…

[leetcode] 54. 螺旋矩阵

文章目录 题目描述解题方法模拟java代码复杂度分析 相似题目 题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;…

js调用html页面需要隐藏某个按钮

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

7-26 单词长度

题目链接&#xff1a;7-26 单词长度 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <stdio.h> #include <stdbool.h>void printLen(int len, bool printOnce) {if (len) {if (printOnce) {printf(" %d",…

微信小程序picker设置了系统年度,打开选择年份从1年开始显示

背景&#xff1a;开发微信小程序时&#xff0c;使用了picker组件&#xff0c;设置值为当前系统时间年份&#xff0c;可以正常回显年份。但是打开面板选择年份的时候&#xff0c;默认从一年开始显示的。如下图所示。 原因&#xff1a;因为绑定的年份字段为Number类型。 解决方案…

性能优化工具

CPU 优化的各类工具 network netperf 服务端&#xff1a; $ netserver Starting netserver with host IN(6)ADDR_ANY port 12865 and family AF_UNSPEC$ cat netperf.sh #!/bin/bash count$1 for ((i1;i<count;i)) doecho "Instance:$i-------"# 下方命令可以…

【AI学习中常见专业英文缩写词的解释】

前言&#xff1a; 为了看着不无聊&#xff0c;文中插入了一些AI生成的狗图片 AI(Artificail Intelligence)人工智能&#xff1a; 让机器模拟和展示人类智能的技术。 GAI(Generative Artificail Intelligence)生成式人工智能: 利用复杂的算法、模型和规则&#xff0c;从大规…

fastjson

一&#xff1a;fastjson作用 1.将Java对象转换为json字符串》响应给前端。 2.将json字符串转换为Java对象 》接受前端的json数据封装到对象中。 二&#xff1a;常用API fastjson API 入口类是 com.alibaba.fastjson.JSON ,常用的序列化操作都可以在JSON类上的静态方法直接完…

DDD领域设计基础

1概述 作为架构师&#xff0c;我们在业务建模的时候不能完全凭经验、感觉&#xff0c;还得有一套方法论&#xff0c;DDD领域驱动设计恰巧可以作为业务建模的方法论来使用。 2 为什么要使用DDD 2.1 为什么需要DDD 复杂系统设计&#xff1a;系统多&#xff0c;业务逻辑复杂&a…

四信遥测终端入选河南省水利先进实用技术推广目录

近期&#xff0c;河南省水利科技推广中心发布通知&#xff0c;四信自主研发的“遥测终端机RTU”&#xff0c;列入河南省水利先进实用技术推广目录&#xff0c;认定为水利先进实用技术。 四信遥测终端 F9164系列 ●一体化设计 ●工业级设计 ●接口丰富、标准易用 ●大容量储存空…
最新文章