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

一般系统的请求认证授权思路【gateway网关+jwt+redis+请求头httpheader】

gateway:网关,我们都知道网关的作用就是对系统的所有请求,网关都会进行拦截,然后做一些操作(例如:设置每个请求的请求头httpHeader,身份认证等等)此时一般会使用到网关过滤器,创建一个过滤器去实现GlobalFilter接口

jwt:JSON-WEB-TOKEN,这里就不过多解释了,同学们可以自行搜索相关文章,它主要包含三个部分,更好的生成token的一种行业规范,主要作用就是令牌校验。

{

        header:xxx,

        payload:xxx,

        singature:xxx

}

redis的主要作用就是为了存放用户信息,该用户信息主要包含以下几个字段

{userCode:xxx,language:xxx,主要是为了进行国际化语言配置比如ZH-CN 、ENmenuApu:["xxx","xxx",..."xxx"] 用户对应的菜单权限列表APIjwtToken:xxx 必须拥有这个字段,为了防止同一个用户在不同机器上登录进行操作
}

httpHeader的主要作用就是存放userCode,用于任何请求都可以获取到当前操作的用户名,比如当我要添加一个新增接口或者更新接口,一般会有两个字段,一个是creator,一个是modifier,那么这两个值就可以直接取请求头的userCode。

还有就是存放language,为了进行国际化语言切换。

所以现在我先给大家画一个图,待会写的代码也是按照这个逻辑,方便大家加深理解与记忆。

现在看一下代码逻辑:

我们创建一个gateway全局过滤器:AuthTokenGlobalFilter

实现GlobalFilter接口,重写如下方法:

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();HttpHeaders headers = request.getHeaders();//得到前端访问请求时的请求头HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.putAll(headers);//先过滤掉登录请求,登录请求不需要进行拦截,直接放行if (ObjectUtil.equals(request.getURI().getPath(), "/login")) {//放行之前将前端发出请求时的请求头拿到,同时设置一下Accept-LanguagehttpHeaders.setAcceptLanguage(httpHeaders.getAcceptLanguage());//放行chain.filter(exchange.mutate().request(decorateRequest(request, httpHeaders)).build());}//其他请求//判读1:请求的请求头中是否携带tokenif (CollectionUtils.isEmpty(headers.get("Authorization"))) {throw new ServiceException(Codes.NO_TOKEN_RECOGNIZED);//未识别到token}//判断2:token解析出来的数据是否能在redis中查询到,考虑到token有可能发生过期,或者是登出了,redis中的数据就会删除String authorization = headers.get("Authorization").get(0);//通过token 利用jwt反解析出数据 claimsJSONObject jsonObject = JwtUtils.parseJwtToken(authorization, "user", NetworkUtils.getIp(request));if (ObjectUtil.isNull(jsonObject)) {throw new ServiceException(Codes.AUTHORIZATION_ERROR);}//如果是登出请求/logout,需要在请求头中加上userCode,为了后续放行之后,拿到该userCode作为redis的key的一部分去删除登录时存到redis中的数据if (ObjectUtil.equals(request.getURI().getPath(), "/logout")) {httpHeaders.set("userCode", jsonObject.get("userCode").toString());return chain.filter(exchange.mutate().request(decorateRequest(request, httpHeaders)).build());}//拿到userCodeString userCode = (String) jsonObject.get("userCode");//去redis中获取数据 key=》 User:userCode 比如User:zkwString key = USER_CACAHE_PREFIX + userCode;String jsonString = stringRedisTemplate.opsForValue().get(key);LoginUser loginUser = JSONObject.parseObject(jsonString, LoginUser.class);if (ObjectUtils.isEmpty(loginUser)) {throw new ServiceException(Codes.LOGIN_EXPIRED);}//走到这里//1、发出的请求的请求头中携带了token//2、携带的token有效,没有过期或者是登出//那么此时还需要进行判断3,判断携带的token与redis中存储的token是否一致,因为有可能有这么一个情况// A用户在机器172.16.254.1上登录一次,成功之后,就会在redis中存放A对应的token以及其他一些字段数据,//那么此时在A发出另外一个请求之前,比如查询,此时A用户又在另外一台机器上172.16.254.2登录,成功之后,也会在redis中存放A在172.16.254.2对应的token以及其他一些字段数据,此时就会覆盖前面redis中存放A在172.16.254.1的token数据了,// 因为生成的token是有根据ip地址的,所以当A用户在机器上172.16.254.1发起请求的时候,携带的token就与此时redis中的token是不对的了,所以对于这种情况我们就不允许存在。if (!ObjectUtil.equals(authorization, loginUser.getJwtToken())) {throw new ServiceException(Codes.LOGIN_EXPIRED);}//如果token都满足情况了,就代表确确实实身份无误了,那么就需要进行用户的权限列表判断了。}

上面是认证逻辑,现在是授权逻辑了。

redis中有两个key,一个key就是刚刚关于认证token的,另一个就是授权的。AccessControl:permissions,这个key的主要作用就是看看前端发出的请求是否是系统里面已经配置的菜单权限API,防止随意伪造请求API。

接下来我们看看授权的代码:

//***********************************************授权*************************************************************//异步获取统里面配置的存在的菜单api,在redis中有存放两个key,一个key就是刚刚前面关于token的,另外一个是关于菜单权限api的//AccessControl:permissionsMenu 这个值的主要作用就是为了判断你请求的api是否此时系统里面有,如果没有的话,有两个原因://  1、你xjb自己随便别写一个请求 2、确确实实开发了这个接口,但是可能在系统菜单表里面忘记添加了//User:userCodeCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {return stringRedisTemplate.opsForValue().get("AccessControl:permissionsMenu");});String permissionsMenu = future.join();//如果不为空,就代表此时系统里面已经配置了菜单权限apiif (permissionsMenu != null) {String[] urls = permissionsMenu.split(",");//当前url不存在系统配置的菜单权限api里面 直接放行if (Arrays.stream(urls).noneMatch(part -> (part.trim()).equals(requestPath))) {return chain.filter(exchange.mutate().request(decorateRequest(request, httpHeaders)).build());}}//如果菜单为空,证明是第一次请求到,把系统里面配置的存在的api设置到该key上else {//通过openFeign远程调用获取系统配置的菜单权限APIList<String> urls = permissionFeign.queryPermissionsMenu();stringRedisTemplate.opsForValue().set("AccessControl:permissionsMenu", urls.toString());//当前url不存在系统配置的菜单权限api里面 直接放行if (urls.stream().noneMatch(part -> (part.trim()).equals(requestPath))) {return chain.filter(exchange.mutate().request(decorateRequest(request, httpHeaders)).build());}}//如果存在,如果判断当前用户是否拥有这个菜单权限apiboolean flag = sysMenuService.queryUserMenuButton(userCode).stream().anyMatch(arg -> ObjectUtil.equals(arg.getApi(), requestPath));if (!flag) {throw new ServiceException(Codes.USER_INSUFFICIENT_PERMISSIONS);}return chain.filter(exchange.mutate().request(decorateRequest(request, httpHeaders)).build());

完整代码:

注意:

登录接口是不需要进行拦截的,我们在登录接口的时候,如果登录成功,才会生成一个token(生成token以及代码中的反解析token在我上一篇文章的工具类有,同学们也可以去看一下)还有查询该用户对应的菜单权限API列表,然后会把相关信息存到redis中去。

总结:

最后:

如果大家觉得这篇文章对你们有所帮助的话,麻烦给个免费的赞赞,也祝各位码农在未来的IT道路上越走越远,谢谢!

相关文章:

一般系统的请求认证授权思路【gateway网关+jwt+redis+请求头httpheader】

gateway&#xff1a;网关&#xff0c;我们都知道网关的作用就是对系统的所有请求&#xff0c;网关都会进行拦截&#xff0c;然后做一些操作&#xff08;例如&#xff1a;设置每个请求的请求头httpHeader&#xff0c;身份认证等等&#xff09;此时一般会使用到网关过滤器&#x…...

c# 正则表达式 帮助类

public class RegexHelper { /// <summary> /// 验证输入字符串是否与模式字符串匹配&#xff0c;匹配返回true /// </summary> /// <param name"input">输入字符串</param> /// <param nam…...

告别mPDF迎来TCPDF和中文打印遇到的问题

mPDF是一个用PHP编写的开源PDF生成库。它最初由Claus Holler创建&#xff0c;于2004年发布。原来用开源软件打印中文没有问题&#xff0c;最近发现新的软件包中mPDF被TCPDF代替了&#xff0c;当然如果只用西文的PDF是没有发现问题&#xff0c;但要打印中文就有点抓瞎了如图1&am…...

mysql 多数据源

依赖 <dependencies><!--mysql连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--多数据源--><dependency><g…...

uniapp 使用renderjs引入echarts

效果图&#xff1a; 1.1renderjs引入echarts 组件zmui-echarts.vue&#xff1a; <template><view class"zmui-echarts" :prop"option" :change:prop"echarts.delay"></view> </template><script>export defaul…...

hr最讨厌这6种应届生简历❌

用求职方法&#xff0c;让你变成offer收割机&#xff0c;是我的责任❗ 简历写得好&#xff0c;面试少不了。最近很多应届生找龙猫帮看简历&#xff0c;我发现很多应届生是真不会写简历啊。 有的简历排版花里胡哨&#xff0c;有的自我评价千篇一律&#xff0c;有的实习经历太过…...

【Linux笔记】文件系统与软硬链接

一、文件系统概述 1.1、先来聊一聊“磁盘” 在讲解文件系统之前&#xff0c;我觉得有必要先聊一下“磁盘”&#xff0c;因为我觉得如果弄懂了磁盘的存储原理&#xff0c;大家可能更容易理解文件系统是怎么管理数据的&#xff0c;并且理解计算机是怎么将磁盘抽象到文件系统的。…...

vue3(笔记)

组合式Api setup-----相当于beforeCreate, create生命周期 reactive–定义状态 对象形式 响应式原理 toRefs— Pinia &#xff08;只有state、getters和actions&#xff09; 更加简洁的语法&#xff0c;完美支持Vue3的Composition api 和 对TypesCcript的完美支持...

Java面向对象 this

this 在Java中&#xff0c;this 是一个特殊的引用变量&#xff0c;它引用了当前对象实例。当在类的非静态方法或构造方法中使用时&#xff0c;this 关键字指代当前的对象实例。它经常用于区分对象的成员变量和局部变量&#xff0c;或者调用其他重载的方法。 以下是一些使用 t…...

阿里云游戏服务器租用价格表,2024最新报价

阿里云游戏服务器租用价格表&#xff1a;4核16G服务器26元1个月、146元半年&#xff0c;游戏专业服务器8核32G配置90元一个月、271元3个月&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价&#xff1a; 阿里云游戏服务器租用价格表 阿…...

2-1 动手学深度学习v2-Softmax回归-笔记

回归 VS 分类 回归估计一个连续值分类预测一个离散类别 从回归到多类分类 回归 单连续数值输出输出的区间&#xff1a;自然区间 R \mathbb{R} R损失&#xff1a;跟真实值的区别 分类 通常多个输出&#xff08;这个输出的个数是等于类别的个数&#xff09;输出的第 i i i…...

laravel distinct查询问题,laravel子查询写法

直接调用后&#xff0c;count查询会和实际查询的数据对不上&#xff0c;count还是查询全部数据&#xff0c;而实际的列表是去重的。 给distinct加上参数&#xff0c;比如去重的值的id&#xff0c;就加id。 另一种写法是使用group by id 子查询。 sql语句&#xff1a; selec…...

AI助力农作物自动采摘,基于DETR(DEtection TRansformer)开发构建作物生产场景下番茄采摘检测计数分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物&#xff0c;专家设计出来了很多用于采摘不同农作物的大型机械&#xff0c;看着非常震撼&#xff0c;但是我们国内农业的发展还是相对比较滞后的&#xff0…...

C语言——字符串大小写互换

前言&#xff1a; 在C语言中&#xff0c;大小写字母相互转换是一个常见的操作。本文将详细介绍C语言中实现大小写字母相互转换的各种方法&#xff0c;并附上代码示例。 目录 一、使用tolower()和toupper()函数 二、使用位操作 三、使用字符串操作函数 一、使用tolower()和t…...

macOS的设置与常用软件(含IntelliJ IDEA 2023.3.2 Ultimate安装,SIP的关闭与开启)

目录 1 系统设置1.1 触控板1.2 键盘 2 软件篇2.1 [科学上网](https://justmysocks5.net/members/)2.1 [安装Chrome浏览器](https://www.google.cn/chrome/index.html)2.2 [安装utools](https://www.u.tools)2.3 [安装搜狗输入法](https://shurufa.sogou.com/)2.4 [安装snipaste…...

http伪造本地用户字段系列总结

本篇记录了http伪造本地用户的多条字段&#xff0c;便于快速解决题目 用法举例&#xff1a; 直接把伪造本地用户的多个字段复制到请求头中&#xff0c;光速解决部分字段被过滤的问题。 Client-IP: 127.0.0.1 Forwarded-For-Ip: 127.0.0.1 Forwarded-For: 127.0.0.1 Forwarded…...

Hadoop-IDEA开发平台搭建

1.安装下载Hadoop文件 1&#xff09;hadoop-3.3.5 将下载的文件保存到英文路径下&#xff0c;名称一定要短。否则容易出问题&#xff1b; 2&#xff09;解压下载下来的文件&#xff0c;配置环境变量 3&#xff09;我的电脑-属性-高级设置-环境变量 4.详细配置文件如下&#…...

block任务块、rescue和always、loop循环、role角色概述、role角色应用、ansible-vault、sudo提权、特殊的主机清单变量

任务块 可以通过block关键字&#xff0c;将多个任务组合到一起可以将整个block任务组&#xff0c;一起控制是否要执行 # 如果webservers组中的主机系统发行版是Rocky&#xff0c;则安装并启动nginx[rootpubserver ansible]# vim block1.yml---- name: block taskshosts: webse…...

Qt:QFileDialog

目录 一、介绍 二、功能 三、具体事例 1、将某个界面保存为图片&#xff0c;后缀名可选PNG、JPEG、SVG等 一、介绍 QFileDialog提供了一个对话框&#xff0c;允许用户选择文件或者目录&#xff0c;也允许用户遍历文件系统&#xff0c;用以选择一个或多个文件或者目录。 QF…...

我的QQ编程学习群

欢迎大家加入我的QQ编程学习群。 群号:950365002 群里面有许多的大学生大佬&#xff0c;有编程上的疑惑可以随时问&#xff0c;也可以聊一些休闲的东西。 热烈欢迎大家加入&#xff01;&#xff01; 上限:150人。...

5个Rust驱动特性解决存储清理难题:Czkawka技术深度解析

5个Rust驱动特性解决存储清理难题&#xff1a;Czkawka技术深度解析 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka Czkawka是一款基于Rust语言开发…...

Hunyuan-MT-7B与SpringBoot整合实战:企业级翻译服务开发

Hunyuan-MT-7B与SpringBoot整合实战&#xff1a;企业级翻译服务开发 1. 引言 在全球化业务快速发展的今天&#xff0c;企业经常需要处理多语言内容。传统翻译方案要么成本高昂&#xff0c;要么响应速度慢&#xff0c;很难满足实时业务需求。腾讯开源的Hunyuan-MT-7B翻译模型&…...

从云端到指尖:巧用Aspose组件实现Office/PDF文档秒级HTML预览,攻克移动端大文件访问瓶颈

1. 移动端大文件预览的痛点与解决思路 最近接手一个企业级项目时&#xff0c;遇到了一个非常典型的场景&#xff1a;用户通过PC端上传各种办公文档&#xff08;Word、Excel、PPT、PDF&#xff09;&#xff0c;需要在移动端随时查看。但当文件体积较大时&#xff08;比如超过50M…...

Phi-3-mini-4k-instruct-gguf开发者案例:为微信小程序后端提供的轻量API服务

Phi-3-mini-4k-instruct-gguf开发者案例&#xff1a;为微信小程序后端提供的轻量API服务 1. 项目背景与需求 在开发微信小程序时&#xff0c;我们经常需要为前端提供智能文本处理能力&#xff0c;比如自动生成商品描述、智能客服回复、内容摘要等。传统方案要么需要调用第三方…...

Gemma-3 Pixel Studio一文详解:Flash Attention 2对图文响应速度提升实测

Gemma-3 Pixel Studio一文详解&#xff1a;Flash Attention 2对图文响应速度提升实测 1. 引言 在当今多模态AI应用快速发展的背景下&#xff0c;Gemma-3 Pixel Studio作为一款基于Google最新开源Gemma-3-12b-it模型构建的高性能对话终端&#xff0c;凭借其卓越的视觉理解能力…...

运算放大器入门难?这篇超详细运算放大器原理与应用指南帮你轻松上手!

1. 运算放大器到底是什么&#xff1f; 第一次接触运算放大器时&#xff0c;我也被这个专业名词吓到了。但后来发现&#xff0c;它其实就是个"超级放大镜"——能把微弱的电信号放大成千上万倍。想象一下医生用的听诊器&#xff0c;它能将微弱的心跳声放大到清晰可闻&a…...

如何获取网易云音乐永久链接:终极免费解决方案指南

如何获取网易云音乐永久链接&#xff1a;终极免费解决方案指南 【免费下载链接】netease-cloud-music-api 网易云音乐直链解析 API 项目地址: https://gitcode.com/gh_mirrors/ne/netease-cloud-music-api 你是否曾经遇到过这样的烦恼&#xff1a;好不容易找到一首喜欢的…...

Git-RSCLIP真实场景测试:城市新区地物分类,住宅区识别效果惊艳

Git-RSCLIP真实场景测试&#xff1a;城市新区地物分类&#xff0c;住宅区识别效果惊艳 1. 模型背景与核心能力 Git-RSCLIP是北航团队基于SigLIP架构专门开发的遥感图像理解模型&#xff0c;在1000万对遥感图文数据集(Git-10M)上进行了深度预训练。与通用视觉模型不同&#xf…...

AI 使用过程中遇到的问题及解决方案

////////////////////////////////////////////////////////////////////////////////////////////////////////context_management: Extra inputs are not permitted Received Model Groupclaude-sonnet-4-6错误原因这是 Claude API 的 context management&#xff08;上下文管…...

客服机器人开放平台能自建知识库吗?以百应Agent为例,探讨成都企业售后自动解答的实现路径

在数字化转型加速的今天&#xff0c;成都作为西部电商和制造业重镇&#xff0c;众多企业面临售后咨询量激增的挑战。退货、物流追踪、产品故障排查等售后问题占客服咨询的 60% 以上&#xff0c;传统人工客服成本高、响应慢&#xff0c;已难以满足用户即时需求。客服机器人开放平…...