从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用

news/2024/9/25 9:51:05/

创建Token

创建token的因素(条件)有很多,在该篇文章中,采用jwt配置和用户基本信息作为生成token的基本因素(读者可根据系统,自由改变生成token因素)。

在JwtPlugInUnit.CS中创建2个方法(JwtPlugInUnit.CS在上一篇文章中有写到)

方法一:PropValuesType方法

/// <summary>
/// 反射获取字段
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static IEnumerable<(string Name, object Value, string Type)> PropValuesType(this object obj)
{List<(string a, object b, string c)> result = new List<(string a, object b, string c)>();var type = obj.GetType();var props = type.GetProperties();foreach (var item in props){result.Add((item.Name, item.GetValue(obj), item.PropertyType.Name));}return result;
}

上述方法:PropValuesType是通过反射获取模型字段和属性。在本文章中,是为了提取登录人员信息,编写成List<Claim>,组成生成token的因素之一。

方法二:BuildToken方法

/// <summary>
/// 生成Token
/// </summary>
/// <param name="loginResult">登陆返回信息</param>
/// <returns></returns>
public static LoginOutPut BuildToken(LoginInput loginResult)
{LoginOutPut result = new LoginOutPut();//获取配置var jwtsetting = AppSettingsPlugInUnit.GetNode<JwtSettingModel>("JwtSetting");//准备calims,记录登录信息var calims = loginResult.PropValuesType().Select(x => new Claim(x.Name, x.Value.ToString(), x.Type)).ToList();//创建headervar key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtsetting.SecurityKey));var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);var header = new JwtHeader(creds);//创建payloadvar payload = new JwtPayload(jwtsetting.Issuer, jwtsetting.Audience, calims, DateTime.Now, DateTime.Now.AddMinutes(jwtsetting.ExpireSeconds));//创建令牌 var token = new JwtSecurityToken(header, payload);var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);result.ExpiresDate = token.ValidTo.AddHours(8).ToString();result.Token = tokenStr;result.UserName = loginResult.UserName;return result;
}

上述方法:BuildToken是创建token的核心代码,它通过用户信息+jwt配置信息生成token,并返回token、用户名、token过期时间等信息(读者可以添加更多返回信息)。

BuildToken中有2个模型,具体结构和位置如下:

创建Model类,用于存放系统中模型。

LoginInput模型结构如下:

/// <summary>
/// 登录输入模型
/// </summary>
public class LoginInput
{/// <summary>/// 用户名/// </summary>public string? UserName { get; set; }/// <summary>/// 密码/// </summary>public string? Password { get; set; }}

LoginOutPut模型结构如下:

/// <summary>/// 登录输入模型/// </summary>public class LoginOutPut{/// <summary>/// 用户名/// </summary>public string? UserName { get; set; }/// <summary>/// 密码/// </summary>public string? Password { get; set; }/// <summary>/// Token/// </summary>public string? Token { get; set; }/// <summary>/// Token过期时间/// </summary>public string? ExpiresDate { get; set; }}

做完以上操作,用户就可以生成Token,但要把token运用到系统中,还需做以下操作。

创建模块分组

在ModeuleGroupEnum.cs中创建2个枚举,具体如下

/// <summary>/// 模块分组/// </summary>public enum ModeuleGroupEnum{/// <summary>/// 系统菜单/// </summary>SysMenu = 1,/// <summary>/// 系统用户/// </summary>SysUser = 2,/// <summary>/// 基础/// </summary>Base = 3,}

新增【系统用户】、【基础】2个枚举。

创建新控制器

创建2个控制器:BaseController和SysUserController,结构如下

创建BaseController基础控制器,它存在的作用,就是承担系统中需要重写方法和获取用户基本信息的桥梁。

代码如下:

/// <summary>
/// 系统基础模块
/// </summary>
[ApiController]
[Route("api/[controller]/[action]")]
[ApiExplorerSettings(GroupName = nameof(ModeuleGroupEnum.Base))]
[Authorize]
public class BaseController : ControllerBase
{/// <summary>/// 获取登陆人员信息/// </summary>/// <returns></returns>[HttpGet]public LoginOutPut GetLoginUserMsg(){StringValues s = new StringValues();var auth = Request.Headers.TryGetValue("Authorization", out s);if (string.IsNullOrWhiteSpace(s))throw new Exception("登录信息失效");var token = new JwtSecurityTokenHandler().ReadJwtToken(s.ToString().Replace($"{JwtBearerDefaults.AuthenticationScheme} ", ""));LoginOutPut loginResult = new(){UserName = token.Claims.FirstOrDefault(f => f.Type == "UserName").Value,Password = Convert.ToString(token.Claims.FirstOrDefault(f => f.Type == "Password").Value),};return loginResult;}
}

解读下该方法:通过获取Headers中的Token,然后使用jwt反解析token获取在BuildToken方法中记录的用户基本信息。

说明:控制器上方存在[Authorize],只要有控制器继承基础控制【BaseController】,那么该控制器下的所有方法,都需要经过jwt验证。如果某一个接口不需要token验证,就在该接口上方添加 [AllowAnonymous]

创建SysUserController控制器,并继承BaseController控制器,它的作用就是承担系统用户的所有接口,具体代码如下:

/// <summary>/// 用户模块/// </summary>[ApiController][Route("api/[controller]/[action]")][ApiExplorerSettings(GroupName = nameof(ModeuleGroupEnum.SysUser))]public class SysUserController : BaseController{/// <summary>/// 获取Token/// </summary>/// <param name="userName">用户名</param>/// <param name="password">密码</param>[HttpGet][AllowAnonymous]public string GetToken(string userName, string password){var loginResult = JwtPlugInUnit.BuildToken(new LoginInput { UserName = userName, Password = password });return loginResult.Token ?? string.Empty;}}

可以看到,该控制器下有2个接口,一个为获取token接口(可同时作为登录接口),一个为获取登录人员信息的接口(继承BaseController下的GetLoginUserMsg()方法)。

做完以上操作,jwt中token验证就完成啦,看一下成果。

不使用token访问接口,不会成功

先获取token

在添加使用token

点击Authorize确定使用

再次访问GetLoginUserMsg()接口,看下效果

文章转载自:陈逸子风

原文链接:https://www.cnblogs.com/cyzf/p/18422784

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构


http://www.ppmy.cn/news/1530233.html

相关文章

828华为云征文|华为云Flexus云服务器X实例Windows系统部署一键短视频生成AI工具moneyprinter

在追求创新与效率并重的今天&#xff0c;我们公司迎难而上&#xff0c;决定自主搭建一款短视频生成AI工具——MoneyPrinter&#xff0c;旨在为市场带来前所未有的创意风暴。面对服务器选择的难题&#xff0c;我们经过深思熟虑与多方比较&#xff0c;最终将信任票投给了华为云Fl…

《微信小程序实战(2) · 组件封装》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

基于python flask的企业财务异常数据分析与预测系统,使用随机森林进行预测,准确率达到98%

研究背景 在现代企业管理中&#xff0c;财务数据的准确性和健康性直接关系到企业的可持续发展。财务数据不仅反映了企业的经营状况&#xff0c;还为企业的未来战略提供了决策依据。然而&#xff0c;随着企业规模的扩大和业务复杂性的增加&#xff0c;财务数据中可能出现各种异常…

鹏哥C语言51---第7次作业:函数的定义和调用

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <math.h> //------------------------------------------------------------------------------------------第 7 次作业 函数定义和调用 //---------------------------…

Prometheus监控k8s环境构建

传统架构中比较流行的监控工具有 Zabbix、Nagios 等&#xff0c;这些监控工具对于 Kubernetes 这类云平台的监控不是很友好&#xff0c;特别是当 Kubernetes 集群中有了成千上万的容器后更是如此&#xff0c;本章节学习下一代的云原生监控平台---Prometheus。 一、基于kuberne…

DBeaver中如何导入excel中的大量数据

之前也让导入过大批量的excel数据&#xff0c;忘记当时怎么导入的了&#xff0c;今天又让导入&#xff0c;感觉手工导入应该是不行的&#xff0c;太费人工了&#xff0c;还是想点办法&#xff0c;于是问了文心一言&#xff0c;操作如下&#xff0c; 在DBeaver中导入Excel中的数…

【AI大模型】通义大模型API接口实现

目录 一、基础环境安装 &#xff08;一&#xff09;OpenAI Python SDK安装 &#xff08;二&#xff09;DashScope SDK安装 二、OPENAI接口实现 &#xff08;一&#xff09;文本输入 &#xff08;二&#xff09;流式输出 &#xff08;三&#xff09;图像输入 &#xff0…

react之jsx基础(2)高频使用场景

文章目录 1. **组件定义**2. **条件渲染**3. **列表渲染**4. **事件处理**5. **嵌套组件**6. **表单处理**7. **样式应用**8. **处理子组件** 在 React 中&#xff0c;JSX 的使用是非常广泛和高频的。以下是一些常见的高频使用场景及其示例&#xff0c;帮助你更好地理解 JSX 的…