GraphQL(六)登录态校验Directive
GraphQL Directive(指令)是GraphQL中的一种特殊类型,它允许开发者在GraphQL schema中添加元数据,以控制查询和解析操作的行为
Directive的详细说明及使用可见GraphQL(五)指令[Directive]详解
本文将介绍通过自定义Directive实现的GraphQL登录态校验,步骤依次为:
Schema
中定义directive
- 实现
DgsReactiveCustomContextBuilderWithRequest
接口,构建请求内全局使用的上下文对象 - 实现
SchemaDirectiveWiring
,对Field
进行拦截校验 Directive
注入
Schema Directive定义
"必须要登录"
directive @needLogin on FIELD_DEFINITIONtype Employee {"雇员名称"employees(month: Date : [String] @needLogin
}
LoginContextBuilder
实现DgsReactiveCustomContextBuilderWithRequest
接口,可以使用当前的请求信息,例如 HTTP 请求头、请求参数等构建自定义的上下文对象
在查询执行过程中,GraphQL 会将该上下文对象传递给所有的数据解析器(DataFetcher),使得数据解析器能够访问和修改上下文对象中的数据
使用DgsReactiveCustomContextBuilderWithRequest
接口可以实现许多有用的功能,例如:
- 存储用户身份验证信息,以便在数据解析器中进行鉴权
- 将请求相关的信息(例如请求参数、请求头等)传递给数据解析器,以便数据解析器根据这些信息返回正确的数据
- 存储请求相关的上下文信息,例如请求开始时间、请求结束时间等,以便进行性能分析和监控
@Component
public class LoginContextBuilder implements DgsReactiveCustomContextBuilderWithRequest<YyContext> {private static final Logger LOGGER = LoggerFactory.getLogger(LoginContextBuilder.class);@Autowiredprivate ReactiveLoginService reactiveLoginService;@Autowiredprivate HttpHeaderAuthorization httpHeaderAuthorization;@NotNull@Overridepublic Mono<LoginContext> build(@Nullable Map<String, ?> map, @Nullable HttpHeaders httpHeaders, @Nullable ServerRequest serverRequest) {boolean interiorAuth = httpHeaderAuthorization.auth(serverRequest);if(interiorAuth){LoginContext loginContext = new LoginContext(true, IpUtil.getClientIpAddress(serverRequest)).setInteriorAuth(true);LOGGER.info("interior request loginContext:{}",loginContext);return Mono.just(loginContext);}else{return reactiveLoginService.getUid(serverRequest).doOnSuccess(user-> LOGGER.info("login user:{}",user)).onErrorResume(e-> Mono.just(LoginUser.NOT_LOGIN_USER)).map(user -> new LoginContext(user, IpUtil.getClientIpAddress(serverRequest)));}}
}
ReactiveLoginService
subscribeOn(Schedulers.boundedElastic())
将该Mono
订阅到一个boundedElastic
调度器的线程中,这样Mono
中的操作就会在该线程上执行,而不会阻塞当前的线程
Schedulers.boundedElastic()
调度器是一个弹性线程池,它根据需要动态地创建和销毁线程,以适应不同的负载情况
public class ReactiveLoginService {private LoginService loginService;public ReactiveLoginService(LoginService loginService){this.loginService = loginService;}/*** 登录校验* @param httpServerRequest* @return*/public Mono<LoginUser> getUid(ServerRequest httpServerRequest){return Mono.fromCallable(()->{long uid = loginService.login(new WebFluxHttpServletRequest(httpServerRequest),null);return uid > 0 ? new LoginUser(uid) : LoginUser.NOT_LOGIN_USER;}).subscribeOn(Schedulers.boundedElastic());}public void close(){loginService.close();}
}
Directive 实现
@Component
public class NeedLoginDirective implements SchemaDirectiveWiring {private static final Logger LOGGER = LoggerFactory.getLogger(NeedLoginDirective.class);public static final String NEED_LOGIN_DIRECTIVE = "needLogin";public NeedLoginDirective() {}@Overridepublic GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition> environment) {GraphQLFieldDefinition field = environment.getElement();GraphQLFieldsContainer parentType = environment.getFieldsContainer();// 原始DataFetcher,无需修改参数值时,最后需返回原始DataFetcher的值DataFetcher originalDataFetcher = environment.getCodeRegistry().getDataFetcher(parentType, field);if (field.getDirective(NEED_LOGIN_DIRECTIVE) == null) {return field;}LOGGER.info("onField field:{} needLogin.", field);DataFetcher needLoginDataFetcher = dfe -> {LoginContext loginContext = DgsContext.getCustomContext(dfe);if (loginContext.getLoginUser().hasLogin()) {return originalDataFetcher.get(dfe);} else {LOGGER.info("not login return null");throw new NeedLoginRuntimeException();}};environment.getCodeRegistry().dataFetcher(parentType, field, needLoginDataFetcher);return field;}
}
Directive 注入
GraphQLSchemaConfiguration
@Configuration
public class GraphQLSchemaConfiguration {@DgsComponentpublic class SecuredDirectiveRegistration {private NeedLoginDirective needLoginDirective;public SecuredDirectiveRegistration(NeedLoginDirective needLoginDirective) {this.needLoginDirective = needLoginDirective;}@DgsRuntimeWiringpublic RuntimeWiring.Builder addSecuredDirective(RuntimeWiring.Builder builder) {return builder.directive(NeedLoginDirective.NEED_LOGIN_DIRECTIVE,needLoginDirective);}}
}
参考资料:
- GraphQL(五)指令[Directive]详解
- Derectives 原理
相关文章:
GraphQL(六)登录态校验Directive
GraphQL Directive(指令)是GraphQL中的一种特殊类型,它允许开发者在GraphQL schema中添加元数据,以控制查询和解析操作的行为 Directive的详细说明及使用可见GraphQL(五)指令[Directive]详解 本文将介绍通过…...

强大的AI语言模型
1.kameAI 点我 1️⃣可以绘图 2️⃣对接4.0 3️⃣具有长篇写作...

成集云 | 鼎捷ERP采购单同步钉钉 | 解决方案
源系统成集云目标系统 方案介绍 鼎捷ERP(Enterprise Resource Planning)是一款综合性的企业管理软件,它包括了多个模块来管理企业的各个方面,其中之一就是采购订单模块。鼎捷ERP的采购订单模块可以帮助企业有效管理和控制采购过程…...

【Kubernetes】Kubernetes的PV和PVC的用法
PV、PVC 前言一、 存储卷1. emptyDir 存储卷1.1 概念1.2 实例 2. hostPath 存储卷2.1 概念2.2 实例 3. nfs共享存储卷 二、PV 和 PVC1. 概念1.1 PV1.2 PVC1.3 PVC 的使用逻辑1.4 创建机制1.5 PV 和 PVC 的生命力周期1.6 创建及销毁 PV 的流程 2. PV 和 PVC 的创建2.1 查看定义2…...

【Redis】Redis三种集群模式-主从、哨兵、集群各自架构的优点和缺点对比
文章目录 前言1. 单机模式2. 主从架构3. 哨兵4. 集群模式总结 前言 如果Redis的读写请求量很大,那么单个实例很有可能承担不了这么大的请求量,如何提高Redis的性能呢?你也许已经想到了,可以部署多个副本节点,业务采用…...
Python爬虫:如何使用Python爬取网站数据
更新:2023-08-13 15:30 想要获取网站的数据?使用Python爬虫是一个绝佳的选择。Python爬虫是通过自动化程序来提取互联网上的信息。本文章将会详细介绍Python爬虫的相关技术。 一、网络协议和请求 在使用Python爬虫之前,我们需要理解网络协…...
剑指offer专题2:队列和栈
用两个栈模拟队列 class CQueue {stack<int> stack1;stack<int> stack2; public:CQueue() {}void appendTail(int value) {stack1.push(value);}int deleteHead() {int val-1;if(!stack2.empty()){val stack2.top();stack2.pop();}else if(!stack1.empty()){while…...
pytorch入门-神经网络
神经网络的基本骨架 import torch from torch import nn #nn模块是PyTorch中用于构建神经网络模型的核心模块。它提供了各种类和函数,可以帮助你定义和训练神经网络。class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() #调用 super(Tudui,…...
kafka使用心得(二)
kafka进阶 消息顺序保证 Kafka它在设计的时候就是要保证分区下消息的顺序,也就是说消息在一个分区中的顺序是怎样的,那么消费者在消费的时候看到的就是什么样的顺序。 消费者和分区的对应关系 参考这篇文章。 分区文件 一个分区对应着log.dirs下的…...

(二)掌握最基本的Linux服务器用法——Linux下简单的C/C++ 程序、项目编译
1、静态库与动态库 静态库(Static Library):静态库是编译后的库文件,其中的代码在编译时被链接到程序中,因此它会与程序一起形成一个独立的可执行文件。每个使用静态库的程序都会有自己的库的副本,这可能会导致内存浪费。常用后缀…...

应急响应-钓鱼邮件的处理思路溯源及其反制
0x00 钓鱼邮件的危害 1.窃取用户敏感信息,制作虚假网址,诱导用户输入敏感的账户信息后记录 2.携带病毒木马程序,诱导安装,使电脑中病毒木马等 3.挖矿病毒的传输,勒索病毒的传输等等 0x01 有指纹的钓鱼邮件的溯源处理…...

Hadoop Hbase Hive 版本对照一览
这里写目录标题 一、Hadoop 与 Hbase 版本对照二、Hadoop 与 Hive 版本对照 官网内容记录,仅供参考 一、Hadoop 与 Hbase 版本对照 二、Hadoop 与 Hive 版本对照...

Postgresql 基础使用语法
1.数据类型 1.数字类型 类型 长度 说明 范围 与其他db比较 Smallint 2字节 小范围整数类型 32768到32767 integer 4字节 整数类型 2147483648到2147483647 bigint 8字节 大范围整数类型 -9233203685477808到9223203685477807 decimal 可变 用户指定 精度小…...
Qt 之 QDebug,QString
文章目录 前言一、QDebug二、QString总结 前言 一、QDebug QDebug是Qt中用于进行调试和输出日志的类。它提供了一种便捷的方式来输出各种类型的数据,并可轻松地与流式输出一起使用,方便调试和查看程序的运行情况。 引入QDebug: 在使用QDebug…...
【C++】面试题
1、都说c是面向对象的语言,面向对象的三个特性能 [展开] 介绍一下吗? 封装:封装是一种集中管理的思想,把内部的数据和实现方法组合在一起,并且不对外暴漏内部的数据和实现方法,只对外提供几个接口来完成函数…...

机器学习算法之-逻辑回归(1)
什么是回归 回归树,随机森林的回归,无一例外他们都是区别于分类算法们,用来处理和预测连续型标签的算法。然而逻辑回归,是一种名为“回归”的线性分类器,其本质是由线性回归变化而来的,一种广泛使用于分类问…...

JAVA多线程和并发基础面试问答(翻译)
JAVA多线程和并发基础面试问答(翻译) java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序…...

正中优配:2023新股上市涨跌幅规则?新股上市涨跌幅限制为几天?
A股与美股不同,股票存在涨跌幅限制,那么,2023新股上市涨跌幅规矩?新股上市涨跌幅限制为几天?下面正中优配为我们预备了相关内容,以供参阅。 2023年新股上市涨跌幅存在以下规矩: 1、主板初次公开…...
如何查看线程在哪个cpu核上
1、ps -eLF查看PSR值 2、 taskset -pc $pid(进程/线程) 参考链接:https://blog.csdn.net/test1280/article/details/87993669...

【Vue前端】设置标题用于SEO优化
原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 文章目录 1.vue全局配置2.创建并暴露getPageTitle方法3.通过全局前置守卫设置title4.页面上引用title5.项目使用中英文翻译,title失效 1.vu…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...