从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用
说明
该文章是属于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(); //创建header
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtsetting.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var header = new JwtHeader(creds); //创建payload
var 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,谢谢。
有兴趣的朋友,请关注我微信公众号吧(*^▽^*)。

关注我:一个全栈多端的宝藏博主,定时分享技术文章,不定时分享开源项目。关注我,带你认识不一样的程序世界
从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用的更多相关文章
- Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述
挤一下: 一开始以为没有多少人用就没建群,但是加我的人太多了,好多问题都是重复的,所以建个群大家互相沟通交流方便点,但是建的有点晚,错过了好多人所以群里人有点少,QQ群: 157216616 小提示 ...
- 权限管理系统系列之WCF通信
目录 权限管理系统系列之序言 首先说下题外话,有些园友看了前一篇[权限管理系统系列之序言]博客加了QQ群(186841119),看了我写的权限管理系统的相关文档(主要是介绍已经开发的功能),给出了一 ...
- express搭建权限管理系统
express搭建权限管理系统 权限管理,是管理系统中的常见组件.通常需要定义资源,把资源调配给用户,通过判断用户是否有权限增删改查来实现. 初衷: 使用express开发过的项目大大小小加在一起也有 ...
- 【vue3-element-admin 】基于 Vue3 + Vite4 + TypeScript + Element-Plus 从0到1搭建后台管理系统(前后端开源@有来开源组织)
vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,技术栈为 Vue3 + Vite4 + T ...
- hexo搭建博客系列(三)美化主题
文章目录 其他搭建 1. 添加博客图标 2. 鼠标点击特效(二选一) 2.1 红心特效 2.2 爆炸烟花 3. 设置头像 4. 侧边栏社交小图标设置 5. 文章末尾的标签图标修改 6. 访问量统计 7 ...
- 学习ASP.NET Core Blazor编程系列三十——JWT登录(4)
学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...
- SpringSecurity权限管理系统实战—三、主要页面及接口实现
系列目录 前言 后端五分钟,前端半小时.. 每次写js都头疼. 自己写前端是不可能的,这辈子不可能自己写前端的,只能找找别人的模板才能维持的了生存这样子.github,gitee上的模板又多,帮助文档 ...
- 基于easyUI实现权限管理系统(三)——角色管理
此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. role.jsp:角色管理界面 <!DOCTYPE html PUBLIC "-//W3 ...
- JVM系列(三):JVM创建过程解析
上两篇中梳理了整个java启动过程中,jvm大致是如何运行的.即厘清了我们认为的jvm的启动过程.但那里面仅为一些大致的东西,比如参数解析,验证,dll加载等等.把最核心的loadJavaVM()交给 ...
- Drools实战系列(三)之eclipse创建工程
web工程和maven工程是目前比较常用的,当然对现在而言,maven工程是开发中最常用的. 两种Drools项目的创建方式,一种是直接创建Drools项目,另一种是基于Maven创建Drools项目 ...
随机推荐
- char字符_C
字符的表示 字符类型由单引号' '包围,字符串由双引号" "包围. //正确的写法 char a = '1'; char b = '$'; char c = 'X'; char ...
- 逆向动态加载Dex(内存加载class)
逆向一个app, 其核心算法是通过反射调用的, 反编译软件中无法找到该类, 并且也无法hook. Java.perform(function(){ Java.enumerateClassLoaders ...
- SpringBoot全局异常处理及自定义异常
首先定义自定义返回类,如果自己项目中已经有了自定义返回类只需要将后面的代码做相应的修改即可: import io.swagger.annotations.ApiModelProperty; impor ...
- 7月24号python:库存管理
7月24号python:库存管理 题目: 仓库管理员以数组 stock 形式记录商品库存表.stock[i] 表示商品 id,可能存在重复.原库存表按商品 id 升序排列.现因突发情况需要进行商品 ...
- 【Shiro】04 ini授权实现
[授权概念] 访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等). 在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permission ...
- OpenAI内讧更多细节曝光:奥特曼离间董事会失败
参考: https://www.thepaper.cn/newsDetail_forward_25512687 ============================== 根据 https://ww ...
- 如何在vscode中支持python的annotation(注解,type checking)——通过设置pylance参数实现python注解的type checking
pylance是vscode的python官方插件的捆绑体,如何在vscode中安装python插件这里不介绍了.pylance的默认设置是不支持python的annotation的,需要我们手动设置 ...
- Kotlin 循环与函数详解:高效编程指南
Kotlin 循环 当您处理数组时,经常需要遍历所有元素. 要遍历数组元素,请使用 for 循环和 in 操作符: 示例 输出 cars 数组中的所有元素: val cars = arrayOf(&q ...
- MPTCP(二):MPTCP版本说明
MPTCP版本说明 简介 参考链接 https://github.com/multipath-tcp/mptcp_net-next/wiki MPTCP的两个版本 MPTCPv0: 在5.6之前的li ...
- 寻访中国100家.NET中大企业 —— 第二站:苏州行
一:事情起因 在.NET圈里混了十多年,相信有不少人知道我专注于玩 .NET高级调试,如今技术上的硬实力还是能够解决市面上的一些疑难杂症,但软实力却在另一个极端,如(人际交往,人情事故),所以就萌生了 ...