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

news/2024/9/23 13:36:06

说明

    该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。

    该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。

    说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。

结合上一篇文章使用,味道更佳:从0到1搭建权限管理系统系列二 .net8 使用JWT鉴权(附当前源码)

有兴趣的朋友,请关注我吧(*^▽^*)。

关注我,学不会你来打我

 创建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个枚举,具体如下

  说明:ModeuleGroupEnum.cs在从0到1搭建权限管理系统系列一 .net8 使用Swagger(附当前源码) 文章中有说明(或者关注我的微信公众号)。

 /// <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()接口,看下效果

回复评论

上一篇文章:从0到1搭建权限管理系统系列二 .net8 使用JWT鉴权(附当前源码)得到了较多评论,有指正的、有疑问的。

首先感谢大家的阅读,感谢大家的指正,也感谢大家的提问。

在这里我针对些问题,回复如下:

回复一:

确实,在.net core 刚发布的时候,所有人在微软的引导下都对这一门的开源的框架,大家都叫它.net core ,它的出现也让c#在生死的边缘,获得一线生机。但在.net core 3.1(应该)之后,就改名叫.net5 .net8等。

回复二:

jwt它是轻量级的库,所有它在这方面的处理,并不是很好。所以建议新增中间件验证过期token或者把Token存到数据库或缓存中,以此来操作复杂的鉴权验证。

回复三:

艾特这2位朋友,你要的来了,顺便求关注博客园、关注微信公众号,不错过每次更新。

感谢你的耐心观看。

如果对你有帮助,请关注我微信公众号吧(*^▽^*)。

源代码地址:https://gitee.com/yangguangchenjie/overall-auth2.0-web-api  

帮我Star,谢谢。

有兴趣的朋友,请关注我微信公众号吧(*^▽^*)。

关注我:一个全栈多端的宝藏博主,定时分享技术文章,不定时分享开源项目。关注我,带你认识不一样的程序世界



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

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

相关文章

任务四:制作二维码

使用草料二维码制作二维码https://cli.im/ 1.选择网址一栏,设置“网址跳转活码”,把网址填入后生成相应二维码 2.此网址为中少年快乐阅读平台http://202.96.31.36:8888/旨在拓展学生课外知识,扩大知识面 3.微信有时会当作不良网页,禁止跳转 把二维码加入海报中 1.成品

Leetcode 65. 有效数字

1.题目基本信息 1.1.题目描述 给定一个字符串 s ,返回 s 是否是一个 有效数字。 例如,下面的都是有效数字:”2″, “0089”, “-0.1”, “+3.14”, “4.”, “-.9”, “2e10”, “-90E3”, “3e+7”, “+6e-1”, “53.5e93”, “-123.456e789″,而接下来的不是:”abc”, “…

结对项目——实现一个自动生成小学四则运算题目的命令行程序

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/这个作业要求在哪里 结对项目 - 作业 - 计科22级34班 - 班级博客 - 博客园 (cnblogs.com)这个作业的目标 结对项目——实现一个自动生成小学四则运算题目的命令行程序成员1 陈奕奕 3222004552成员2 林闰…

任务三:pdf转换器应用

本次添加水印我使用的lightPDF网页进行水印的添加工作https://lightpdf.com/ 1.首先要先注册账号 2.可以使用浏览器对网页进行翻译 3.在“pdf工具栏”中找到第三列“编辑pdf”的位置,选择“水印pdf” 4.把需要添加水印的文件添加到网页中 5.对水印的大小,透明度,颜色,内容进…

wordpress网站维护教程:不能上传文件,数据库报错的解决方法

当WordPress网站遇到不能上传文件或数据库报错的问题时,这可能会影响网站的正常使用。下面分别针对这两种情况提供一些可能的解决方法。 不能上传文件权限问题:检查上传文件的目标目录权限是否正确。通常,WordPress的上传目录(默认为/wp-content/uploads/)应该具有可写的权…

人工智能第三次课程

第三次课程学习了思维导图的制作 分享了多个工具 我下载了亿图 选择的主题是田忌赛马 我是以面向学生为主体制作的田忌赛马 包括作者 主题 故事要素 取胜原因四个部分 可以清晰的帮助学生逐步理解所学内容

海报制作:校园安全

我所选的主题是校园安全教育,校园安全是当下每一个校园都应该注重的事情。海报的制作更贴合于校园学习氛围,以书籍为右侧的部分,在黑板上写下主题题目,更贴合于课堂。花朵点缀,附加儿童安全歌读起来朗朗上口,让学生们的印象更深刻。下方学生与教师形象与日常课堂相仿,学…

为什么我的 PHP 数据库连接失败?

PHP 数据库连接失败可能有多种原因,以下是一些常见的原因及其解决方法:数据库凭证错误:检查数据库连接时使用的用户名和密码是否正确。如果数据库的凭证发生了变化,请确保在 PHP 中也进行了更新。数据库服务器未运行:确认数据库服务器(如 MySQL, PostgreSQL, SQLite 等)…