ASP.NET Core JWT
目录
Session的缺点
JWT(Json Web Token)
优点:
登录流程
JWT的基本使用
生成JWT
解码JWT
用JwtSecurityTokenHandler对JWT解码
注意
Session的缺点
- 对于分布式集群环境,Session数据保存在服务器内存中就不合适了,应该放到一个中心状态服务器上。ASP.NET Core支持Session采用Redis、Memcached。
- 中心状态服务器有性能问题。
JWT(Json Web Token)
- JWT把登录信息(也称作令牌)保存在客户端。
- 为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理,而签名的密钥只有服务器端才知道,每次服务器端收到客户端提交过来的令牌的时候都要检查一下签名。
优点:
- 状态保存在客户端,适合分布式系统。
- 签名保证了客户端无法数据造假。
- 性能更高,不需要和中心状态服务器通讯,纯内存计算。
登录流程
- 客户端向服务器端发送用户名,密码等请求登录。
- 服务器端校验用户名,密码,如果校验成功,则从数据库中取出这个用户的ID、角色等用户相关信息。
- 服务器端采用只有服务器端才知道的密钥来对用户信息的JSON字符串进行签名,形成签名数据。
- 服务器端把用户信息的JSON字符串和签名拼接到一起形成JWT,然后发送给客户端。
- 客户端保存服务器端返回的JWT,并且在客户端每次向服务器端发送请求的时候都带上这个JWT。
- 每次服务器端收到浏览器请求中携带的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(Json Web Token) 优点: 登录流程 JWT的基本使用 生成JWT 解码JWT 用JwtSecurityTokenHandler对JWT解码 注意 Session的缺点 对于分布式集群环境,Session数据保存在服务器内存中就不合适了&#…...
Linux基础命令之Nginx中的rewrite功能(重新)
一、什么是Rewrite Rewrite也称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。 1. URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如http://www.123.com/news/index.php?id123 使…...
4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)
文章目录 前言一、Ajax技术(从服务端获取数据,发送各种请求)0 接口文档管理:使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例(几年前的早期用法) 二、 Axios技术(对原…...
三星手机为何不大力扩展中国市场?
三星在中国市场的手机销量长期低迷,主要原因可以归结为以下几点,这也解释了为什么三星可能没有大力扩展中国市场的计划: 1. 市场竞争激烈 中国市场已经被华为、OPPO、vivo、小米和苹果等品牌牢牢占据,这些品牌在产品设计、本地化…...
Linux在x86环境下制作ARM镜像包
在x86环境下制作ARM镜像包(如qemu.docker),可以通过QEMU和Docker的结合来实现。以下是详细的步骤: 安装QEMU-user-static QEMU-user-static是一个静态编译的QEMU二进制文件,用于在非目标架构上运行目标架构的二进制文…...
【算法篇】贪心算法
目录 贪心算法 贪心算法实际应用 一,零钱找回问题 二,活动选择问题 三,分数背包问题 将数组和减半的最小操作次数 最大数 贪心算法 贪心算法,是一种在每一步选择中都采取当前状态下的最优策略,期望得到全局最优…...
硬件电路基础
目录 1. 电学基础 1.1 原子 1.2 电压 1.3 电流 1.电流方向: 正极->负极,正电荷定向移动方向为电流方向,与电子定向移动方向相反。 2.电荷(这里表示负电荷)运动方向: 与电流方向相反 1.4 测电压的时候 2. 地线…...
iOS 音频录制、播放与格式转换
iOS 音频录制、播放与格式转换:基于 AVFoundation 和 FFmpegKit 的实现 在 iOS 开发中,音频处理是一个非常常见的需求,比如录音、播放音频、音频格式转换等。本文将详细解读一段基于 AVFoundation 和 FFmpegKit 的代码,展示如何实现音频录制、播放以及 PCM 和 AAC 格式之间…...
探索前端框架的未来:Svelte 的崛起
引言 在前端开发的世界里,框架更新换代的速度仿佛光速。从 jQuery 到 Angular,再到如今大热的 React 和 Vue,开发者们不断追逐更轻量、更快、更易于维护的框架。如今,Svelte 正悄然崛起,并引发了关于前端框架未来的热烈…...
Gitea+Gridea 创建个人博客
历史文档存档,该方法目前已经无法使用,部署方法可供参考 Gitea部分 1.关于Gitea Gitea 是一个面向开源及私有软件项目的托管平台,是全球最大的代码托管平台之一。它采用 Git 分布式版本控制系统,为开发者提供了代码托管、版本控…...
DeepSeek-V3:开源多模态大模型的突破与未来
目录 引言 一、DeepSeek-V3 的概述 1.1 什么是 DeepSeek-V3? 1.2 DeepSeek-V3 的定位 二、DeepSeek-V3 的核心特性 2.1 多模态能力 2.2 开源与可扩展性 2.3 高性能与高效训练 2.4 多语言支持 2.5 安全与伦理 三、DeepSeek-V3 的技术架构 3.1 模型架构 3…...
通过制作docker镜像的方式在阿里云部署前端后台服务
前端Dockerfile文件的内容: FROM nginx:版本,如果不指定,默认是latest COPY dist/ /usr/share/nginx/html/dist COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 端口 前端sh脚本文件内容: appName项目名 tar -xvf dist.tar …...
无界构建微前端?NO!NO!NO!多系统融合思路!
文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…...
Linux(CentOS)安装 Nginx
CentOS版本:CentOS 7 Nginx版本:1.24.0 两种安装方式: 一、通过 yum 安装,最简单,一键安装,全程无忧。 二、通过编译源码包安装,需具备配置相关操作。 最后附:设置 Nginx 服务开…...
【提示词工程】探索大语言模型的参数设置:优化提示词交互的技巧
在与大语言模型(Large Language Model, LLM)进行交互时,提示词的设计和参数设置直接影响生成内容的质量和效果。无论是通过 API 调用还是直接使用模型,掌握模型的参数配置方法都至关重要。本文将为您详细解析常见的参数设置及其应用场景,帮助您更高效地利用大语言模型。 …...
GNN多任务预测模型实现(二):将EXCEL数据转换为图数据
目录 一. 引言 二. 加载和检查数据 三. 提取特征和标签 四. 标准化特征 五. 构建节点索引 六. 构建边及其特征 七. 总结 八. 结语 一. 引言 在图神经网络(Graph Neural Networks, GNNs)的多任务学习场景中,数据预处理是至关重要的一…...
.net的一些知识点6
1.写个Lazy<T>的单例模式 public class SingleInstance{private static readonly Lazy<SingleInstance> instance new Lazy<SingleInstance>(() > new SingleInstance());private SingleInstance(){}public static SingleInstance Instace > instance…...
Java 线程池:7参数配置、4拒绝策略与执行流程详解
1. 为什么需要线程池? 在 Java 并发编程中,线程的创建和销毁是一项昂贵的操作。频繁地创建和销毁线程会带来较高的系统开销,甚至可能因线程数过多而导致 OOM(OutOfMemoryError) 或 CPU 过载。 线程池(Thre…...
SQL带外注入
SQL 带外注入(Out-of-Band SQL Injection, OOB SQLi) 是 SQL 注入的一种特殊类型,主要用于以下情况: 数据库没有直接返回错误信息(比如被防火墙拦截了)。无法使用常规注入手法(如 UNION、错误信…...
MySQL知识点总结(一)
1.SQL分类 数据定义(DDL):创/改/删/名/清(cadrt) 数据库对象:表/视图/存储/函数/触发器/事件 数据操作(DML):增/删/改/查(idus) 操作数据库对象 数据控制&…...
【报错解决】MySQL报错:sql_mode=only_full_group_by
文章目录 报错信息 DataGrip 报错还原Navicat 报错还原 报错原因解决方案 查看当前 sql mode方案一:临时解决方案二:永久解决方案三:使用 any_value() 或 group_concat()方案四:调整实现思路,避开 GROUP BY 使用 我…...
【华为OD机考】华为OD笔试真题解析(1)--AI处理器组合
一、题目描述 某公司研发了一款高性能AI处理器,每台物理设备具备8颗AI处理器,编号分别为0、1、2、3、4、5、6、7。 编号0~3的处理器处于同一链路中,编号4~7的处理器处于另外一个链路中,不同链路中的处理器不能通信,如…...
【redis】缓存设计规范
本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明: 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析: 是否需要排序?: zset(有序集合)用…...
Node.js 实现简单爬虫
介绍 爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。 本文将使用 Nodejs 编写一个简单的爬虫脚本,爬取一个美食网站,获取菜品的标题和图片链接,并以表格的形式输出。 准备工作 1、初始化项目 首先࿰…...
一次奇怪的空指针问题分析:事务、死锁与隐式回滚
最近我们在排查一个诡异的 空指针异常,整个分析过程可以说是跌宕起伏,最终的结论也颇具隐蔽性。今天就把这个问题分享出来,希望对大家有所帮助。 问题现象 在系统中,我们有 单据 B,它通过一个 关联 ID 字段与 上级单…...
数据结构-基础
1、概念: 程序 数据结构 算法 2、程序的好坏 可读性,稳定性,扩展性,时间复杂度,空间复杂度。 3、数据结构 是指存储、组织数据的方式,以便高效地进行访问和修改。通过选择适当的数据结构, 能…...
问题大集04-浏览器阻止从 本地 发起的跨域请求,因为服务器的响应头 Access-Control-Allow-Origin 设置为通配符 *
1、问题 localhost/:1 Access to XMLHttpRequest at xxx(请求) from origin http://localhost:xxx(本地) has been blocked by CORS policy: The value of the Access-Control-Allow-Origin header in the response must not be t…...
音频进阶学习十二——Z变换一(Z变换、收敛域、性质与定理)
文章目录 前言一、Z变换1.Z变换的作用2.Z变换公式3.Z的状态表示1) r 1 r1 r12) 0 < r < 1 0<r<1 0<r<13) r > 1 r>1 r>1 4.关于Z的解释 二、收敛域1.收敛域的定义2.收敛域的表示方式3.ROC的分析1)当 …...
leetcode——组合总和(回溯算法详细讲解)
在面试或刷题过程中,回溯算法是一个绕不开的核心算法之一。今天,我们来详细解析 LeetCode 39「组合总和」 问题,并用 Java 回溯 剪枝优化 来高效解决它!这篇文章不仅适合初学者,也适合希望提高回溯算法的朋友们。 给你…...
说一下JVM管理的常见参数
Java虚拟机(JVM)有许多常见参数,用于控制其行为和性能。以下是一些常见的JVM参数及其说明: 1. 内存管理参数 -Xms<size> START 设置初始堆内存大小。例如,-Xms512m表示初始堆大小为512MB。 -Xmx<size>…...
leetcode_47全排列II
1. 题意 给一个含有重复数字的数组,求不重复的排列。 2. 题解 将数组进行排序,当回溯发生的时候,找到下个不重复的元素即可。 class Solution { public:void genPerm(std::vector<std::vector<int>> &ans, std::vector&l…...
pytest-xdist 进行多进程并发测试!
在软件开发过程中,测试是确保代码质量和可靠性的关键步骤。随着项目规模的扩大和复杂性的增加,测试用例的执行效率变得尤为重要。为了加速测试过程,特别是对于一些可以并行执行的测试用 例,pytest-xdist 提供了一种强大的工具&…...
【CPP】CPP经典面试题
文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…...
STM32的HAL库开发---通用定时器(TIMER)---定时器脉冲计数
一、脉冲计数实验原理 1、 外部时钟模式1:核心为蓝色部分的时基单元,时基单元的时钟源可以来自四种,分别是内部时钟PCLK、外部时钟模式1,外部时钟模式2、内部定时器触发(级联)。而脉冲计数就是使用外部时钟…...
在C#中,Array,List,ArrayList,Dictionary,Hashtable,SortList,Stack的区别
Array Array你可以理解为是所有数组的大哥 普通数组 : 特点是长度固定, 只能存储相同类型的数据 static void Main(string[] args){//声明int[] ints;string[] strings;People[] peoples;//默认值 //int 类型是 0//string 类型是 nullint[] ints1 { 1, 2, 3 };string[] …...
Ollama 部署本地大语言模型
一、下载安装ollama 1.百度 ollama Ollama 2.点击下载 可以复制下载链接,使用下载器下载。 3.双击安装 默认安装目录:C:\Users\用户名\AppData\Local\Programs\Ollama 二、更改模型下载目录 0.默认下载目录 (跳过) 之前没下载过模型,不…...
sql批量更新和删除语句
1.更新一条数据 update om_sellorder set SOSTATUS2 where id 283d3eb87b134e1c993b70b018406285 2.更新多个数据为某一个特点值 string ID context.Request["ID"]; //需要替换‘,’逗号,不然识别不出ID数据这里注意 ‘ID’ 是一个逗号(&a…...
探索从传统检索增强生成(RAG)到缓存增强生成(CAG)的转变
在人工智能快速发展的当下,大型语言模型(LLMs)已成为众多应用的核心技术。检索增强生成(RAG)(RAG 系统从 POC 到生产应用:全面解析与实践指南)和缓存增强生成(CAG&#x…...
基于ArcGIS的SWAT模型+CENTURY模型模拟流域生态系统水-碳-氮耦合过程研究
流域是一个相对独立的自然地理单元,它是以水系为纽带,将系统内各自然地理要素连结成一个不可分割的整体。碳和氮是陆地生态系统中最重要的两种化学元素,而在流域系统内,水-碳-氮是相互联动、不可分割的耦合体。随着流域内人类活动…...
深入浅出:机器学习的全面解析
深入浅出:机器学习的全面解析 引言 机器学习(Machine Learning, ML)作为人工智能的一个重要分支,近年来取得了显著进展,并在多个领域中得到了广泛应用。本文将从基础概念、核心算法、应用场景以及未来发展趋势等方面…...
go运算符
内置运算符 算术运算符关系运算符逻辑运算符位运算符赋值运算符 算术运算符 注意: (自增)和–(自减)在 Go 语言中是单独的语句,并不是运算符 package mainimport "fmt"func main() {fmt.Printl…...
w196Spring Boot高校教师科研管理系统设计与实现
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
SQL Server 数据库迁移到 MySQL 的完整指南
文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…...
安卓7以上抓包证书安装
安卓7以上抓包证书安装 fiddler 用户可以直接试试这个文件 前提是要root过了,如果是模拟器就很容易开启 前提:要有openssl工具,在linux一个指令就可以下载了:sudo apt-get install openssl,windons则是在https://www.openssl.org/…...
C基础寒假练习(8)
一、终端输入10个学生成绩,使用冒泡排序对学生成绩从低到高排序 #include <stdio.h> int main(int argc, const char *argv[]) {int arr[10]; // 定义一个长度为10的整型数组,用于存储学生成绩int len sizeof(arr) / sizeof(arr[0]); // 计算数组…...
10. k8s二进制集群之Kube Scheduler部署
在开始之前需要准备什么?创建kube-scheduler证书请求文件【即证书的生成⓵】根据上面证书配置文件生成kube-scheduler证书【即证书的生成⓶】创建与关联kube-scheduler配置文件(为后面生成系统服务做准备)创建kube-scheduler服务配置文件【准备系统服务⓵】创建kube-schedul…...
低代码开发与传统开发:未来的技术路线选择
在科技飞速发展的当下,软件开发技术日新月异,低代码开发与传统开发作为两种重要的开发模式,正站在未来技术路线选择的十字路口,引发了众多企业和开发者的关注。它们各自有着独特的优势和适用场景,究竟该如何抉择&#…...
HIVE如何注册UDF函数
如果注册UDF函数的时候报了上面的错误,说明hdfs上传的路径不正确, 一定要用下面的命令 hadoop fs -put /tmp/hive/111.jar /user/hive/warehouse 一定要上传到上面路径,这样在创建函数时,引用下面的地址就可以创建成功...
Got socket exception during request. It might be caused by SSL misconfiguration
引入xutils3依赖,结果包找不到 maven里面添加阿里云镜像 核心 maven { url uri("https://maven.aliyun.com/nexus/content/groups/public/") }repositories {google()maven { url uri("https://maven.aliyun.com/nexus/content/groups/public/"…...
ORACLE 数据库的启动和关闭
文章目录 1、 启动 ORACLE 数据库的三步操作2、 关闭 ORACLE 数据库的三步操作3 、启动和关闭 ORACLE 数据库的相关命令4、 启动和关闭 ORACLE 数据库 1、 启动 ORACLE 数据库的三步操作 1、启动数据库并使它可用,有三步操作:a、启动一个实例b、装配数据…...