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

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数据保存在服务器内存中就不合适了&#…...

查询引擎:它们是什么以及为什么重要

了解查询引擎、它们的优势以及如何简化现代应用程序的数据管理。查询引擎是高效处理和检索数据的强大工具&#xff0c;但并非所有查询引擎都能满足现代应用程序对速度和实时性的需求。在本文中&#xff0c;我们将解析查询引擎的定义、主要优势以及它们如何用于实时数据和AI应用…...

03/29 使用 海康SDK 对接时使用的 MysqlUtils

前言 最近朋友的需求, 是需要使用 海康sdk 连接海康设备, 进行数据的获取, 比如 进出车辆, 进出人员 这一部分是 资源比较贫瘠时的一个 Mysql 工具类 测试用例 public class MysqlUtils {public static String MYSQL_HOST "192.168.31.9";public static int MY…...

2025.2.7 Python开发岗面试复盘

2025.2.7 Python开发岗面试复盘 问题: 是否了解过其他语言? 了解过Java、JavaScript、C等语言,但主要技术栈是Python。 Python跟Java的区别? Python是解释型语言,Java是编译型语言 Python动态类型,Java静态类型 Python简洁易读,Java相对严谨复杂 Python GIL限制并发,Java并…...

一个sql只能有一个order by

ORDER BY 子句在 SQL 中只能出现一次&#xff0c;静态部分和动态部分只能写一个 ORDER BY...

Windows Docker笔记-在容器中运行项目

在文章《Windows Docker笔记-Docker容器操作》中&#xff0c;已经成功创建了容器&#xff0c;也就是建好了工厂&#xff0c;接下来就应该要安装流水线设备&#xff0c;即运行项目达到生产的目的。 在Ubuntu容器中新建项目 这里要新建一个简单的C项目&#xff0c;步骤如下&…...

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…...

寒假2.5

题解 web:[网鼎杯 2020 朱雀组]phpweb 打开网址&#xff0c;一直在刷新&#xff0c;并有一段警告 翻译一下 查看源码 每隔五秒钟将会提交一次form1&#xff0c;index.php用post方式提交了两个参数func和p&#xff0c;func的值为date&#xff0c;p的值为Y-m-d h:i:s a 执行fu…...

定期删除一周前的数据,日志表的表空间会增长吗?

即使定期删除一周前的数据&#xff0c;日志表的表空间仍可能持续增长。原因如下&#xff1a; 删除操作不释放空间&#xff1a;DELETE 操作只会标记数据为删除状态&#xff0c;并不会立即释放空间。这些空间可以被后续的 INSERT 操作重用&#xff0c;但不会自动缩减表的总大小。…...

yum 安装mysql

sudo yum install mysql-server sudo systemctl start mysqld sudo systemctl enable mysqld 获取临时 root 密码并登录 MySQL 安装完成后&#xff0c;MySQL 会生成一个临时的 root 密码。你可以通过查看日志文件来找到这个密码&#xff1a; sudo grep ‘temporary password’…...

Servlet笔记(下)

HttpServletRequest对象相关API 获取请求行信息相关(方式,请求的url,协议及版本) | API | 功能解释 | | ----------------------------- | ------------------------------ | | StringBuffer getRequestURL(); | 获取客户端…...

Windows 中学习Docker环境准备3、在Ubuntu中安装Docker

Windows 中学习Docker环境准备1、Win11安装Docker Desktop Windows 中学习Docker环境准备2、Docker Desktop中安装ubuntu Windows 中学习Docker环境准备3、在Ubuntu中安装Docker 需要更多Docker学习视频和资料&#xff0c;请文末联系 步骤 1&#xff1a;更新系统并安装依赖…...

【centOS】搭建公司内网git环境-GitLab 社区版(GitLab CE)

1. 安装必要的依赖 以 CentOS 7 系统为例&#xff0c;安装必要的依赖包&#xff1a; sudo yum install -y curl policycoreutils openssh-server openssh-clients postfix sudo systemctl start postfix sudo systemctl enable postfix2. 添加 GitLab 仓库 curl -sS https:/…...

Unity DoTween使用文档

DoTween 使用文档 DoTween 是 Unity 中非常流行的动画补间插件。它通过链式调用方式&#xff0c;让开发者可以快速创建平滑、自然的动画效果。本文将介绍 DoTween 的基础用法、缓动曲线原理&#xff08;包含常见缓动曲线的数学公式与参数说明&#xff09;、案例演示以及一些常…...

【办公类-99-01】20250201学具PDF打印会缩小一圈——解决办法:换一个PDF阅读器

背景需求&#xff1a; 2024年1月13日&#xff0c;快要放寒假了&#xff0c;组长拿着我们班的打印好的一叠教案来调整。 “前面周计划下面的家园共育有调整&#xff0c;你自己看批注。” “还有你这个教案部分的模版有问题&#xff0c;太小&#xff08;窄&#xff09;了。考虑…...

组合总和II(力扣40)

这道题的难点就在于题目所给的集合中有重复的数字&#xff0c;我们需要进行去重操作。首先明确去重指的是去重哪一部分。注意并不是对递归的集合去重&#xff0c;而是对当前集合的遍历进行去重。这么说可能有点抽象&#xff0c;举个例子&#xff1a;假设集合为1,1,2,3,4&#x…...

基于HTML生成网页有什么优势

在互联网时代&#xff0c;网页是人们获取信息、交流互动的重要窗口&#xff0c;而基于HTML生成网页&#xff0c;是搭建网络大厦的关键。HTML语法简洁直观&#xff0c;标签和属性语义明确&#xff0c;新手也能迅速上手&#xff0c;创建包含基础元素的网页&#xff0c;极大降低了…...

php 接入扣子的 token获取

本身逻辑只是个api&#xff0c;但是官方不提供php的sdk 扎心了老铁&#xff0c;这下php 狗都不用了&#xff0c;主要麻烦的是如何获取access_token&#xff0c;代码如下 protected function get_jwt(): string{$header [alg > RS256,typ > JWT,kid > $this->kid];…...

Redis02 - 持久化

Redis持久化 文章目录 Redis持久化一&#xff1a;持久化简介1&#xff1a;Redis为什么要进行持久化2&#xff1a;Redis持久化的方式 二&#xff1a;RDB持久化介绍1&#xff1a;手动触发RDB2&#xff1a;自动触发RDB3&#xff1a;redis.conf中进行RDB的配置4&#xff1a;RDB优缺…...

【力扣】240.搜索二维矩阵 II

题目 我的代码 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {for(int i0;i<matrix.size();i){for(int j0;j<matrix[0].size();j){if(targetmatrix[i][j]){return true;}else if(target<matrix[i][j]){brea…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...