当前位置: 首页 > article >正文

ASP.NET Core JWT

目录

Session的缺点

JWT(Json Web Token)

优点:

登录流程

JWT的基本使用

生成JWT

解码JWT

用JwtSecurityTokenHandler对JWT解码

注意


Session的缺点

  1. 对于分布式集群环境,Session数据保存在服务器内存中就不合适了,应该放到一个中心状态服务器上。ASP.NET Core支持Session采用Redis、Memcached。
  2. 中心状态服务器有性能问题。

JWT(Json Web Token)

  1. JWT把登录信息(也称作令牌)保存在客户端。
  2. 为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理,而签名的密钥只有服务器端才知道,每次服务器端收到客户端提交过来的令牌的时候都要检查一下签名。

优点:

  1. 状态保存在客户端,适合分布式系统。
  2. 签名保证了客户端无法数据造假。
  3. 性能更高,不需要和中心状态服务器通讯,纯内存计算。

登录流程

  1. 客户端向服务器端发送用户名,密码等请求登录。
  2. 服务器端校验用户名,密码,如果校验成功,则从数据库中取出这个用户的ID、角色等用户相关信息。
  3. 服务器端采用只有服务器端才知道的密钥来对用户信息的JSON字符串进行签名,形成签名数据。
  4. 服务器端把用户信息的JSON字符串和签名拼接到一起形成JWT,然后发送给客户端。
  5. 客户端保存服务器端返回的JWT,并且在客户端每次向服务器端发送请求的时候都带上这个JWT。
  6. 每次服务器端收到浏览器请求中携带的JWT后,服务器端用密钥对JWT的签名进行校验,如果校验成功,服务器端则从JWT中的JSON字符串中读取用户的信息。这样服务器端就知道这个请求对应的用户了。

JWT的基本使用

NuGet:System.IdentityModel.Tokens.Jwt

生成JWT

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;//claim是一个键值对,用来存储用户信息,比如用户id,用户名,角色等
var claims = new List<Claim>()
{new Claim(ClaimTypes.NameIdentifier, "123"),new Claim(ClaimTypes.Name, "ljy"),new Claim(ClaimTypes.Role, "admin"),new Claim(ClaimTypes.Role, "user"),new Claim("Passport", "E90000082"),new Claim("Id", "E90000082")
};
string key = "jddsjf54$$%45445%^$gvdfgd8d454dgji34jk";
//设置过期时间,30分钟后过期
DateTime expires = DateTime.Now.AddMinutes(30);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
//对称秘钥
var secKey = new SymmetricSecurityKey(keyBytes);
//签名凭据
var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
//创建jwtSecurityToken
var tokenDescriptor = new JwtSecurityToken(claims: claims,//声明expires: expires,//过期时间signingCredentials: credentials//签名凭据);
//生成token
string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
Console.WriteLine(jwt);

解码JWT

using System.Text;string jwt = "eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEyMyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJsankiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOlsiYWRtaW4iLCJ1c2VyIl0sIlBhc3Nwb3J0IjoiRTkwMDAwMDgyIiwiSWQiOiJFOTAwMDAwODIiLCJleHAiOjE3Mzg4MzAxMTB9.frI1BwyedlIfuIcWgkxfNsbXkaJJ01M3iNo7wXt6Fy8";string[] strs = jwt.Split('.');
string header = JwtDecode(strs[0]);
string payload = JwtDecode(strs[1]);
Console.WriteLine("---head---");
Console.WriteLine(header);
Console.WriteLine("---payload---");
Console.WriteLine(payload);string JwtDecode(string s)
{s = s.Replace('-', '+').Replace('_', '/');switch (s.Length % 4){case 2:s += "==";break;case 3:s += "=";break;}var bytes = Convert.FromBase64String(s);return Encoding.UTF8.GetString(bytes);
}

用JwtSecurityTokenHandler对JWT解码

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;string jwt = "eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEyMyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJsankiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOlsiYWRtaW4iLCJ1c2VyIl0sIlBhc3Nwb3J0IjoiRTkwMDAwMDgyIiwiSWQiOiJFOTAwMDAwODIiLCJleHAiOjE3Mzg4MzAxMTB9.frI1BwyedlIfuIcWgkxfNsbXkaJJ01M3iNo7wXt6Fy8";string secKey = "jddsjf54$$%45445%^$gvdfgd8d454dgji34jk";
JwtSecurityTokenHandler tokenHandler = new();
//设置验证参数
TokenValidationParameters valParam = new();
SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secKey));
//获取或设置用于签名验证的 SecurityKey
valParam.IssuerSigningKey = securityKey;
//不验证发行者
valParam.ValidateIssuer = false;
//不验证接受者
valParam.ValidateAudience = false;
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,valParam, out SecurityToken secToken);
foreach (Claim claim in claimsPrincipal.Claims)
{Console.WriteLine($"{claim.Type}={claim.Value}");
}

注意

负载中的内容是明文形式保存的;
不要把不能被客户端知道的信息放到JWT中;

相关文章:

ASP.NET Core JWT

目录 Session的缺点 JWT&#xff08;Json Web Token&#xff09; 优点&#xff1a; 登录流程 JWT的基本使用 生成JWT 解码JWT 用JwtSecurityTokenHandler对JWT解码 注意 Session的缺点 对于分布式集群环境&#xff0c;Session数据保存在服务器内存中就不合适了&#…...

原生redis实现分布式锁

用 原生 Redis&#xff08;Jedis、Lettuce&#xff09; 实现分布式锁&#xff0c;可以参考 Redisson 的原理&#xff0c;但需要自己处理锁的自动续期、故障恢复等细节。核心思路是使用 Redis 的 SET NX EX 或 SET PX NX 命令来实现互斥锁&#xff0c;并利用 Lua 脚本 保障原子性…...

光伏-报告显示,假期内,硅料端签单顺序发货相对稳定。若3月份下游存提产,则不排除硅料价格有上调预期。

据TrendForce集邦咨询报告显示&#xff0c;假期内&#xff0c;硅料端按照前期签单顺序发货&#xff0c;相对稳定。若3月份下游存提产&#xff0c;则不排除硅料价格有上调预期。 002306中科云网 旅游 | 公司为提供复合菜系特色餐饮的连锁企业&#xff0c;形成了以粤菜&#xff…...

【信息系统项目管理师-案例真题】2017上半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题1】8 分【问题2】4 分【问题3】8 分【问题4】5 分试题二【问题1】10 分【问题2】8 分【问题3】6 分【问题4】5 分试题三【问题1】5 分【问题2】7 分【问题3】6 分【问题4】3 分试题一 阅读下列说明…...

滴水逆向_程序实现弹窗修改OEP

作业&#xff1a; 几个很重要的注意事项。 1 我们模拟的是内核如何将一个文件硬盘中拉伸到内存中&#xff0c;但是我们做的仅仅是 模拟拉伸过程。也就是说其中的属性字段是无差别的拷贝的。 但是加载exe的时候 &#xff0c;imagebase 是随机分配的。 我们打开内存中的exe&…...

快速上手——.net封装使用DeekSeek-V3 模型

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,用爱发电,去丈量人心,是否能达到人机合一?开工大吉 新的一年就这么水灵灵的开始了,在这里,祝各位读者新春快乐,万事如意! 新年伊…...

ReactNative进阶(五十九):存量 react-native 项目适配 HarmonyOS NEXT

文章目录 一、前言二、ohos_react_native2.1 Fabric2.2 TurboModule2.2.1 ArkTSTurboModule2.2.2 cxxTurboModule&#xff1a; 三、拓展阅读 一、前言 2024年10月22日19:00&#xff0c;华为在深圳举办“原生鸿蒙之夜暨华为全场景新品发布会”&#xff0c;主题为“星河璀璨&…...

1-2 面向对象编程方法

1.0 面向对象编程思维 在面向对象风格中&#xff0c;结构体被看做数据&#xff08;data&#xff09;&#xff0c;而操作数据的函数称作方法&#xff08;method&#xff09;。目前函数 和数据是分离的&#xff0c;函数并不直接操作数据&#xff0c;我们需要拿到函数返回的结果&a…...

k8s中部署nginx的pod

在当今数字化的浪潮中&#xff0c;容器编排技术成为了构建和管理应用程序的核心力量。Kubernetes&#xff08;简称 k8s&#xff09;作为容器编排领域的佼佼者&#xff0c;凭借其强大的自动化部署、扩展和管理能力&#xff0c;深受开发者和运维人员的青睐。而 Nginx 作为一款高性…...

CSS 组合选择符详解与实战示例

在 Web 开发过程中&#xff0c;CSS 用于定义页面元素的样式&#xff0c;而选择器则帮助我们精确定位需要添加样式的元素。今天我们主要来讲解 CSS 中的组合选择符&#xff0c;它们能够根据 DOM 结构中元素之间的关系来选中目标元素&#xff0c;从而写出结构清晰、易于维护的 CS…...

html为<td>添加标注文本

样式说明&#xff1a; /*为td添加相对定位点*/ .td_text {position: relative; }/*为p添加绝对坐标(相对于父元素中的定位点)*/ .td_text p {position: absolute;top: 80%;font-size: 8px; }参考资料&#xff1a;...

apachePoi中XSSFClientAnchor图片坐标简述;填充多张图片

概述 业务中经常会遇到在单元格内填充图片的需求&#xff0c;而且要求指定图片在单元格内的位置。 一般都是用的apache的poi&#xff0c;设置图片坐标。 HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)dx1 dy1 起始单元…...

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…...

数据留痕的方法

在项目中&#xff0c;数据变更时&#xff0c;经常需要记录上次的数据&#xff0c;以便查看对比&#xff0c;专业术语叫做数据留痕。数据变更留痕&#xff08;即记录数据的变更历史&#xff09;是一个常见的需求&#xff0c;例如在审计、追踪数据变化或满足合规性要求的场景中。…...

Glustefs 服务端配置流程

Glustefs 服务端配置流程 &#xff08;一&#xff09;环境搭建 名称ip硬件设备文件虚拟机 gluster1192.168.101.12G新磁盘/dev/sdb虚拟机 gluster2192.168.101.22G新磁盘/dev/sdb虚拟机 gluster3192.168.101.32G新磁盘/dev/sdb &#xff08;二&#xff09;磁盘格式化&#x…...

为飞牛OS基于FRP的内网穿透开启HTTPS加密

前言 玩NAS的朋友应该有比较多只是在家庭局域网使用&#xff0c;比如日常看看电影、备份手机照片什么的&#xff0c;这属于家庭局域网的使用场景。 当然了&#xff0c;如果你经常出差&#xff0c;或者过年回家不想把NAS也背回去&#xff0c;或者是想上班摸鱼&#xff0c;或者是…...

《基于Python与DashScope的智能语音合成工具开发》

《基于Python与DashScope的智能语音合成工具开发》 在当今数字化时代&#xff0c;语音合成技术已经广泛应用于各种场景&#xff0c;如智能语音助手、有声读物、导航系统等。本文将介绍如何使用Python和DashScope平台开发一个简单而功能强大的文字转语音工具。通过这个工具&…...

快速上手Vim的使用

Vim Linux编辑器-vim使用命令行模式下所有选项都可以带数字底行模式可视块模式&#xff08;ctrlV进入&#xff09; Linux编辑器-vim使用 Vim有多种模式的编辑器。能帮助我们很快的进行代码的编辑&#xff0c;甚至完成很多其他事情。 默认情况下我们打开vim在命令模式下&#x…...

vue学习第四天 v-on事件绑定

v-on绑定事件如下&#xff0c;点击按钮会弹出alert v-on&#xff1a;事件具体名称“事件调用的函数名” 事件调用的函数写在methods里面 在methods属性的函数里&#xff0c;可以用this获取data的数据&#xff0c;this代表的就是整个vue实例 用this.age就可以拿到age&#xff0…...

2.8寒假作业

web&#xff1a;[HNCTF 2022 Week1]2048 之前也做过类似的题目&#xff0c;之前的解法是直接get传参score20000&#xff0c;可以尝试 打开环境看源代码&#xff0c;直接改源代码显然是不行的&#xff0c;那么用一下上面的办法也不行&#xff0c;估计是要改其他方向的&#xff…...

PyTorch torch.sign函数介绍

torch.sign 是 PyTorch 库中用于计算输入张量每个元素符号的函数。下面从功能概述、函数原型、参数解释、返回值、使用示例以及与相关函数对比等方面详细介绍 torch.sign。 功能概述 torch.sign 函数会返回一个与输入张量形状相同的新张量&#xff0c;其中每个元素的值表示输…...

Formality:时序变换(五)(寄存器复制)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生&#xff0c;它们包括&#xff1a;时钟门控(Clock Gating)、寄存器合并(Register Merging)、…...

音频知识基础

音频知识基础 声音属性声音度量人耳特性通道数音频数字化传输接口 声音属性 响度 响度是人耳对声音强弱的主观感受&#xff1b; 主要和声波的振幅相关&#xff0c;同时也和频率有一定关系&#xff1b; 音调 音调是人耳对声音高低的主观感受&#xff1b; 主要与频率相关&#…...

科技赋能数字内容体验的核心技术探索

内容概要 在数字化时代&#xff0c;科技的迅猛发展为我们的生活和工作带来了深刻的变革。数字内容体验已经成为人们获取信息和娱乐的重要途径&#xff0c;而这背后的技术支持则扮演着至关重要的角色。尤其是在人工智能、虚拟现实和区块链等新兴技术的推动下&#xff0c;数字内…...

DeepSeek-R1 本地大模型搭建对接API

DeepSeek-R1 在这里将学到很多知识 欢迎使用使用DeepSeek-R1本地大模型DeepSeek 的模型基础说明DeepSeek的本地 API 说明DeepSeek 本地模型搭建1、执行命令安装及测试 DeepSeek-R1 API接口调用当然&#xff0c;我们为了让用户更加便捷&#xff0c;我们把API 接口全部放到上面截…...

利用NestJS构建高效的RESTful API接口

1. 引言 项目背景与目标 随着互联网应用的快速发展,RESTful API已成为前后端分离架构中的重要组成部分。本文将介绍如何使用NestJS构建一个高效且可维护的RESTful API接口。目标是通过NestJS的模块化和依赖注入特性,实现一个易于扩展和维护的API系统。 RESTful API的重要性…...

redis高级数据结构布隆过滤器

文章目录 背景什么是布隆过滤器Redis 中的布隆过滤器布隆过滤器使用注意事项实现原理空间占用估计 背景 我们在使用新闻客户端看新闻时&#xff0c;它会给我们不停地推荐新的内容&#xff0c;它每次推荐时要去重&#xff0c;去掉那些已经看过的内容。问题来了&#xff0c;新闻…...

《Wiki.js知识库部署实践 + CNB Git数据同步方案解析》

一、wiki.js 知识库简介 基本概述 定义 &#xff1a;Wiki.js 是一个开源、现代、轻量且功能强大的 Wiki 应用程序&#xff0c;基于 Node.js 构建&#xff0c;旨在帮助个人和团队轻松创建、管理和共享知识。开源性质 &#xff1a;它遵循 AGPLv3 许可证&#xff0c;任何人都可以…...

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中&#xff0c;处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性&#xff0c;帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性&#xff1f; overflow 属性用于控制当元素的内容…...

.yml文件_YAML格式文件

.yml 文件是 YAML&#xff08;YAML Ain’t Markup Language&#xff09;格式的一种文件扩展名。YAML 是一种用于数据序列化的语言&#xff0c;通常用于配置文件、数据交换、日志记录等场景。它以可读性高、简洁的格式为特点&#xff0c;非常适合用于人类阅读和编写。YAML 通常被…...