.NET、VUE利用RSA加密完成登录并且发放JWT令牌设置权限访问

news/2023/12/1 1:15:10

后端生成公钥私钥

使用RSA.ToXmlString(Boolean) 方法生成公钥以及私钥。

RSACryptoServiceProvider rSA = new();
string pubKey = rSA.ToXmlString(false);//公钥
string priKey = rSA.ToXmlString(true);//私钥

后端将生成的公钥发送给前端 

创建一个get请求,将后端生成的公钥发送给前端,需要注意,这里生成的公钥是XML格式需要转换为pkcs8格式,前端JS只能处理pkcs8格式,私钥不能发给前端!!!!

这里需要安装一个包XC.RSAUtil用于转换格式。

Install-Package XC.RSAUtil -Version 1.3.6

[HttpGet]
public object Edd()
{var keyList = RsaKeyConvert.PublicKeyXmlToPem(pubKey);//将xml格式转换为Pkcs8return keyList;
}

前端使用公钥加密密码 

 使用的加密库为JSEncrypt库,安装JSEncrypt库。

npm install jsencrypt -D

页面引用 

import {JSEncrypt} from 'jsencrypt'

 界面

<div id="JWT"><div>账号:<input type="text" v-model="MyName"/></div><div>密码:<input type="text" v-model="MyPassword"/></div><button @click="Myinput">登录</button>
</div>

 保存账号密码以及后端发送过来的公钥。

data() {return {MyName: null,//账号MyPassword: null,//密码pubKey:null,//公钥JWTkey:null//JWT令牌}
}

 在使用登录界面时调用函数接收公钥并且保存。

created() {PostJwtEdd().then(res=>{this.pubKey=res}).catch(err => {console.log(err)})
}

 前端在输入账号密码后,对密码进行加密,将加密后的密码发送请求给后端,对比成功后前端将JWT令牌保存。

methods:{Myinput(){var encryptor = new JSEncrypt()encryptor.setPublicKey(this.pubKey)var rsaPassWord = encryptor.encrypt(this.MyPassword)//加密密码PostJwtDdd(this.MyName, rsaPassWord).then(res => {this.JWTkey=res//将后端生成的JWT令牌保存}).catch(err => {console.log(err)})}
}

发送密码的axio请求部分

export function PostJwtDdd(MyName,MyPassword){return request({method: 'post',url: '/JWTS/Ddd',data:{MyName,MyPassword}})
}

 这是发送的账号以及密码密文。

32d927f2022941459cf1df93cfaf9763.png

 后端接收参数对比

 后端接收得到参数,将密码密文进行解密。

创建一个类用于接收账号和加密后的密文。

public class RsaKey
{public string MyName { get; set; }public string MyPassword { get; set; }
}

 接收参数开始解密对比账号密码。

[HttpPost]
public object Ddd([FromBody] RsaKey rsaKey)
{rsa.FromXmlString(priKey);//传入私钥进行解密byte[] cipherbytex;cipherbytex = rsa.Decrypt(Convert.FromBase64String(rsaKey.MyPassword), false);var c = Encoding.UTF8.GetString(cipherbytex);//转换为string类型MyDbContext md = new MyDbContext();//对数据库表创建实体类var user = md.MyIntroductions.Where(x => x.MyName == rsaKey.MyName).Select(x => x.MyPassword);//数据库中寻找该账号对应的密码string users = null;foreach (var v in user){users = v;}if (user == null){return new { err = "账号错误" };}else{if (users == c){//登录成功}else{return new { err = "密码错误" };}}
}

 生成JWT令牌

登录成功之后开始生成JWT令牌并且返回给前端,在登录成功哪里生成。

需要安装两个包。

包1:System.IdentityModel.Tokens.Jwt

Install-Package System.IdentityModel.Tokens.Jwt

包2:Microsoft.AspNetCore.Authentication.JwtBearer

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

List<Claim> claims = new List<Claim>();
claims.Add(new Claim("MyName", rsaKey.MyName));
claims.Add(new Claim(ClaimTypes.Role, rsaKey.MyName));//颁发管理员角色
string key = jwtSettingsOpt.Value.SecKey;
DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSeconds);
byte[] secBytes = Encoding.UTF8.GetBytes(key);
var seckey = new SymmetricSecurityKey(secBytes);
var credentials = new SigningCredentials(seckey, SecurityAlgorithms.HmacSha256Signature);
var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials);
string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
return jwt;

这是前端接收到的JWT令牌

c607913874a0466f9c2926d03d6cefa1.png

 后端权限访问

 后端创建一个post请求,该请求带有[Authorize]

[Authorize]是一个用于处理权限的,在这里的作用就是对没有JWT令牌的请求返回401错误,也就是我们可以利用这一点来对登录的用户开放一些权限,如果没有JWT令牌那么就无法请求到数据。

该post请求会返回请求人的账号。

[Authorize]
[HttpPost]
public object Bdd()
{return this.User.FindFirst("MyName")!.Value;
}

 前端带JWT令牌进行访问

需要注意的是JWT令牌是通过'Authorization'的一个请求头发送过去,格式必须为:

Authorization:Bearer+一个空格+后端生成的JWT令牌

前端界面

<button @click="MyJwt">查看权限</button>
MyJwt(){var JwtKey='Bearer '+this.JWTkeyconsole.log(JwtKey)PostJwtBdd(JwtKey).then(res=>{console.log(res)}).catch(err=>{console.log(err)})
}

axios请求部分

export function PostJwtBdd(JwtKey){return request({method: 'post',url: '/JWTS/Cdd',headers: {'Authorization': JwtKey}})
}

在后端请求中配置了[Authorize(Roles ="admin")]后,只有在Roles指定的用户才能对其接口进行访问,一般可以用于对管理员的访问,在生成JWT令牌的时候,

通过claims.Add(new Claim(ClaimTypes.Role, '用户'));来进行匹配,管理员用户。

 该post请求只有用户为admin的才能请求

[Authorize(Roles ="admin")]//配置只有管理员角色才能请求
[HttpPost]
public object Cdd()
{return this.User.FindFirst("MyName")!.Value;
}

 前端界面

<button @click="OneJwt">管理员权限</button>
OneJwt(){var JwtKey='Bearer '+this.JWTkeyconsole.log(JwtKey)PostJwtCdd(JwtKey).then(res=>{console.log(res)}).catch(err=>{console.log(err)})
}

axios请求部分,同样请求也只能通过'Authorization': 请求头进行发送。

Authorization+"空格"+生成的JWT令牌

export function PostJwtCdd(JwtKey){return request({method: 'post',url: '/JWTS/Cdd',headers: {'Authorization': JwtKey}})
}

如果带有的是错误的JWT令牌,那么后端会返回401错误,如图所示:

f781a71d731a47c58f9fd4bd7e4e36ac.png

并且不会返回任何的对象。

2b36c695fc414624b4cb1487b33596bb.png


http://www.ppmy.cn/news/1177045.html

相关文章

低概率Bug,研发敷衍说复现不到

测试工作中&#xff0c;经常会遇到一些低概率出现的问题&#xff0c;如果再是个严重问题&#xff0c;那测试人员的压力无疑是很大的&#xff0c;一方面是因为低概率难以复现&#xff0c;另一面则是来自项目组的压力。 如何在测试时减少此类问题的重复投入&#xff0c;我的思考如…

LoongArch 指令集实验exp6

在借鉴了友佬的代码后&#xff0c;终于是跑通了测试。 1. 2. 4. 5. 6. 还需要改一个&#xff08;&#xff09; assign sr64_result {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5代码 mycpu_top.v module mycpu_to…

python html(文件/url/html字符串)转pdf

安装库 pip install pdfkit第二步 下载程序wkhtmltopdf https://wkhtmltopdf.org/downloads.html 下载7z压缩包 解压即可, 无需安装 解压后结构应该是这样, 我喜欢放在项目里, 相对路径引用(也可以使用绝对路径, 放其他地方) import pdfkit# 将 wkhtmltopdf.exe程序 路径 p…

Stable Diffusion WebUI扩展canvas-zoom详细讲解

canvas-zoom这是什么? 这是一个针对画布做一些操作的工具,比如缩放等。 下面来详细说一下这些操作的热键。 重要的热键: 缩放(Alt+滚轮)、移动画布 (F)、全屏 (S) 和重置缩放 (R) (1)Shift + wheel - 缩放画布 按住Shift + 滚轮之后,一点反应都没有,之后按…

typedef __packed struct 中的__packed意义

typedef __packed struct 是C语言中用于定义紧凑结构体的语法。__packed关键字用于告诉编译器不要为结构体成员添加填充字节&#xff0c;从而使得结构体的大小更加紧凑。typedef关键字用于为数据类型定义一个新的名称。 下面是一个使用__packed和typedef的示例代码&#xff1a…

066:mapboxGL的marker的drag,dragstart,dragend三种触发事件示例

第066个 点击查看专栏目录 本示例是演示如何在vue+mapbox中处理marker的三种触发事件drag,dragstart,dragend。 marker通过on(‘XXX’, callback),的方式进行触发处理。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(…

linux工具篇

文章目录 linux工具篇1. linux 软件包管理器-yum1.1 什么是软件包1.2 yum的使用1.3 yum源 2. linux编辑器-vim2.1 vim概念2.2 vim各个模式切换2.3 vim正常模式命令汇总2.4 vim底行模式各命令汇总2.5 vim的简单配置 3. Linux编译器-gcc/g使用3.1 复习程序编译过程(1) 预处理(2) …

SLAM从入门到精通(三边测量法详解)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 三边测量&#xff0c;或者说叫三角定位&#xff0c;是定位系统中很常见的一种测量方法。它最主要的原理就是依靠已有的三个特征坐标和半径&#xf…

Python基础入门例程13-NP13 格式化输出(三)

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解答&#xff1a; 1&#xff09;第一种strip函数 2&#xff09;先删除左边&#xff0c;再删除右边的空格&#xff0c;使用.lstrip函数和 .rstrip函数 3) 使用replace函数 4)使用split和join函数&#xff0c…

Jmeter压测工具和Docker服务端接口压测的安装使用详细教程

安装 参考资料 版本 切换语言 使用步骤 1、新建线程组&#xff1b; 右键“测试计划”(左侧导航中的第一条) > 添加 > 线程&#xff08;用户&#xff09; > 线程组&#xff1b; 线程数&#xff1a;并发数&#xff1b; 2、添加取样器 > HTTP请求&#xff1b; 右…

题目 1120: C语言训练-“水仙花数“问题2python详解)——练气三层后期

✨博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;算法修炼之练气篇&#xff08;C\C版&#xff09; &#x1f353;专栏&#xff1a;算法修炼之筑基篇&#xff08;C\C版&#xff09; &#x1f352;专栏&#xff1a;算法修炼之练气篇&#xff08;Python版&#xff09; ✨…

数据结构——10.24

这里写目录标题 回文双向栈双向队列1双向队列2 回文 #include<bits/stdc.h> using namespace std;bool is_huiwen( string s) {for(int i 0; i < s.size() / 2; i){if( s[i] ! s[ s.size() - i - 1 ] ){return false;}}return true; }int main(){string ss;int opt…

边缘计算:云计算的延伸

云计算已经存在多年&#xff0c;并已被证明对大大小小的企业都有好处&#xff1b;然而&#xff0c;直到最近边缘计算才变得如此重要。它是指发生在网络边缘的一种数据处理&#xff0c;更接近数据的来源地。 这将有助于提高效率并减少延迟以及设备和云之间的数据传输成本。边缘…

JVM详解(InsCode AI 创作助手)

JVM是一个虚拟的计算机&#xff0c;它有自己的硬件架构&#xff0c;如处理器、堆栈和寄存器等&#xff0c;也有自己的指令系统。JVM的主要任务是负责加载、验证、编译和执行Java程序。 一、JVM参数默认配置如下 内存设置&#xff1a; 初始堆内存大小&#xff1a;物理内存的1/…

NSS [SWPUCTF 2021 新生赛]sql

NSS [SWPUCTF 2021 新生赛]sql 很明显是sql&#xff0c;有waf。 参数是wllm get型传参&#xff0c;有回显&#xff0c;单引号闭合&#xff0c;回显位3 跑个fuzz看看waf 过滤了空格 and 报错注入 空格->%09 ->like and->&&爆库&#xff1a;test_db -1%27uni…

spring-初识spring

初识spring Spring简介 初识spring一、Spring 特性二、IOC容器(反转控制)1、IOC容器1.1、IOC思想1.2、IOC容器在Spring中的实现 2、基于XML管理bean2.1入门案例2.2获取bean2.3依赖注入(DI)2.3.1set方法注入2.3.1构造器注入 2.4 为类类型属性赋值2.4.1 引用外部已声明bean2.4.2 …

采用节省空间的封装W25Q128JWPIM、W25Q128JWEIQ、W25Q128JWSIM、W25Q128JWBIQ (128M-bit) 串行闪存

W25Q128JW 1.8V 128M-BIT SERIAL FLASH MEMORY WITH DUAL, QUAD SPI 描述 W25Q128JW (128M-bit) 串行闪存阵列分为65&#xff0c;536个可编程页面&#xff0c;每个页面256字节。一次最多可编程256个字节。页面可以以16个为一组&#xff08;4KB扇区擦除&#xff09;、128个为一…

【QT开发(14)】QT P2P chat 聊天

在【P2P学习&#xff08;2&#xff09;】P2P 通信&#xff0c;主要存在四种不同的网络模型的第一阶段&#xff1a;集中式P2P 模式 最简单的路由方式就是集中式&#xff0c;即存在一个中心节点保存了其他所有节点的索引信息&#xff0c;索引信息一般包括节点 IP 地址、端口、节…

STM32G030F6P6点灯闪烁

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff08;2&#xff0…

电子邮件发送接收原理(附 go 语言实现发送邮件)

前言 首先要了解电子邮件的发送接收&#xff0c;不是点到点的。我想给你传达个消息&#xff0c;不是直接我跑到你家里喊你&#xff1a;“嘿&#xff0c;xxx&#xff0c;是你的益达&#xff0c;快拿走”。 而是类似快递的发送收取方式&#xff0c;是有服务器的中转的。我先将我…
最新文章