GraphQL(六)登錄態校驗Directive

GraphQL Directive(指令)是GraphQL中的一種特殊類型,它允許開發者在GraphQL schema中添加元數據,以控制查詢和解析操作的行為

Directive的詳細說明及使用可見GraphQL(五)指令[Directive]詳解

本文將介紹通過自定義Directive實現的GraphQL登錄態校驗,步驟依次為:

  1. Schema中定義directive
  2. 實現DgsReactiveCustomContextBuilderWithRequest接口,構建請求內全局使用的上下文對象
  3. 實現SchemaDirectiveWiring,對Field進行攔截校驗
  4. 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);}}
}

參考資料:

  1. GraphQL(五)指令[Directive]詳解
  2. Derectives 原理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38456.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38456.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38456.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

勘探開發人工智能技術:機器學習(6)

0 提綱 7.1 循環神經網絡RNN 7.2 LSTM 7.3 Transformer 7.4 U-Net 1 循環神經網絡RNN 把上一時刻的輸出作為下一時刻的輸入之一. 1.1 全連接神經網絡的缺點 現在的任務是要利用如下語料來給apple打標簽&#xff1a; 第一句話&#xff1a;I like eating apple!(我喜歡吃蘋…

06 json數據解析和列表控件

內容回顧 json數據解析 json ----- 對要傳輸的數據進行封裝的工具 json是由json數組([]) 和 json對象({})在qt中,對JSON數據進行處理(解析和打包) JSON數據處理所要包含的類: QJsonDocument -----它的作用是將數據轉換成json文檔 QJsonArray ---- json數組,就是封裝多個…

User-Agent介紹

User-Agent介紹 引言 在Web開發中&#xff0c;我們經常會遇到需要根據不同的用戶設備或瀏覽器類型來進行特定處理的情況。為了達到這樣的目的&#xff0c;我們可以使用User-Agent這個HTTP頭信息字段來識別用戶的設備和瀏覽器。本篇文章將介紹User-Agent的基本概念、用法以及在…

SpringBoot 學習(02): 從嵌入式系統到嵌入式Servlet SpingBoot 的進化之路

嵌入式系統 計算機操作系統啟動后&#xff0c;會加載一系列的功能和服務&#xff0c;而這些東西都不是開發操作系統的人寫的&#xff0c;如果想讓一個生態快速崛起&#xff0c;那么操作系統的開發人&#xff0c;就要告訴大家&#xff0c;在這個操作系統上&#xff0c;你要遵守…

3.1 Ansible 的使用和配置管理

Ansible 的使用和配置管理 文章目錄 Ansible 的使用和配置管理Ansible 基礎Ansible 模塊和變量主機管理和組織角色和劇本部署應用和配置自動化與批量操作Ansible 常見用例Ansible 最佳實踐和性能優化 大綱 Ansible 簡介和特點 介紹 Ansible 的定義和作用&#xff0c;以及它在配…

【Java】Guava的Striped類。

Striped類,它提供了一種線程安全的分段鎖(Striped Locking)機制。 Striped類可以用于將一組資源或操作分成多個段(Stripes),每個段上都有一個獨立的鎖。這種機制可以在并發訪問時提供更好的性能,因為不同線程可以同時訪問不同的段而不會相互阻塞。通常,Striped鎖適用于…

pytorch3d成功安裝

一、pytorch3d是什么&#xff1f; PyTorch3D的目標是幫助加速深度學習和3D交叉點的研究。3D數據比2D圖像更復雜&#xff0c;在從事Mesh R-CNN和C3DPO等項目時&#xff0c;我們遇到了一些挑戰&#xff0c;包括3D數據表示、批處理和速度。我們開發了許多有用的算子和抽象&#xf…

【Visual Studio Code】--- Win11 安裝 VS Code 超詳細

Win11 安裝 VS Code 超詳細 概述一、下載 Vscode二、安裝 Vscode 概述 一個好的文章能夠幫助開發者完成更便捷、更快速的開發。書山有路勤為徑&#xff0c;學海無涯苦作舟。我是秋知葉i、期望每一個閱讀了我的文章的開發者都能夠有所成長。 一、下載 Vscode Vscode官網 二、…

HTTP和HTTPS協議

目錄 一、HTTP和HTTPS區別&#x1f33b; 二、有了https還有使用http場景嗎&#x1f34a; 三、https協議的工作原理&#x1f4a5; 四、https協議的優點和缺點&#x1f35e; 一、HTTP和HTTPS區別&#x1f33b; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTT…

時序預測 | MATLAB實現基于KNN K近鄰的時間序列預測-遞歸預測未來(多指標評價)

時序預測 | MATLAB實現基于KNN K近鄰的時間序列預測-遞歸預測未來(多指標評價) 目錄 時序預測 | MATLAB實現基于KNN K近鄰的時間序列預測-遞歸預測未來(多指標評價)預測結果基本介紹程序設計參考資料 預測結果 基本介紹 基于KNN K近鄰的時間序列預測-遞歸預測未來(多指標評價) …

macOS - 安裝使用 libvirt、virsh

文章目錄 關于 libvirt使用安裝啟動服務virsh 交互模式virsh 幫助命令 關于 libvirt libvirt 官網&#xff1a; https://libvirt.org/gitlab : https://gitlab.com/libvirt/libvirtgithub : https://github.com/libvirt/libvirt 只讀&#xff0c;gitlab 的鏡像 libvirt是一套…

機器學習之數據集

目錄 1、簡介 2、可用數據集 3、scikit-learn數據集API 3.1、小數據集 3.2、大數據集 4、數據集使用 ?所屬專欄&#xff1a;人工智能 文中提到的代碼如有需要可以私信我發給你&#x1f60a; 1、簡介 當談論數據集時&#xff0c;通常是指在機器學習和數據分析中使用的一組…

ES 概念

es 概念 Elasticsearch是分布式實時搜索、實時分析、實時存儲引擎&#xff0c;簡稱&#xff08;ES&#xff09;成立于2012年&#xff0c;是一家來自荷蘭的、開源的大數據搜索、分析服務提供商&#xff0c;為企業提供實時搜索、數據分析服務&#xff0c;支持PB級的大數據。 -- …

logstash 原理(含部署)

1、ES原理 原理 使?filebeat來上傳?志數據&#xff0c;logstash進??志收集與處理&#xff0c;elasticsearch作為?志存儲與搜索引擎&#xff0c;最后使?kibana展現?志的可視化輸出。所以不難發現&#xff0c;?志解析主要還 是logstash做的事情 從上圖中可以看到&#x…

RDMA概述

1. DMA和RDMA概念 1.1 DMA DMA(直接內存訪問)是一種能力&#xff0c;允許在計算機主板上的設備直接把數據發送到內存中去&#xff0c;數據搬運不需要CPU的參與。 傳統內存訪問需要通過CPU進行數據copy來移動數據&#xff0c;通過CPU將內存中的Buffer1移動到Buffer2中。DMA模…

【圖像分類】理論篇 (4)圖像增強opencv實現

隨機旋轉 隨機旋轉是一種圖像增強技術&#xff0c;它通過將圖像以隨機角度進行旋轉來增加數據的多樣性&#xff0c;從而幫助改善模型的魯棒性和泛化能力。這在訓練深度學習模型時尤其有用&#xff0c;可以使模型更好地適應各種角度的輸入。 原圖像&#xff1a; 旋轉后的圖像&…

1.MySQL數據庫的基本操作

數據庫操作過程&#xff1a; 1.用戶在客戶端輸入 SQL 2.客戶端會把 SQL 通過網絡發送給服務器 3.服務器執行這個 SQL,把結果返回給客戶端 4.客戶端收到結果,顯示到界面上 數據庫的操作 這里的數據庫不是代表一個軟件&#xff0c;而是代表一個數據集合。 顯示當前的數據庫 …

Python中的MetaPathFinder

MetaPathFinder 是 Python 導入系統中的一個關鍵組件&#xff0c;它與 sys.meta_path 列表緊密相關。sys.meta_path 是一個包含 MetaPathFinder 實例的列表&#xff0c;這些實例用于自定義模塊的查找和加載邏輯。當使用 import 語句嘗試導入一個模塊時&#xff0c;Python 會遍歷…

Golang通過alibabaCanal訂閱MySQLbinlog

最近在做redis和MySQL的緩存一致性&#xff0c;一個方式是訂閱MySQL的BinLog文件&#xff0c;我們使用阿里巴巴的Canal的中間件來做。 Canal是服務端和客戶端兩部分構成&#xff0c;我們需要先啟動Canal的服務端&#xff0c;然后在Go程序里面連接Canal服務端&#xff0c;即可監…

Maven - 統一構建規范:Maven 插件管理最佳實踐

文章目錄 Available Plugins開源項目中的使用插件介紹maven-jar-pluginmaven-assembly-pluginmaven-shade-pluginShade 插件 - 標簽artifactSetrelocationsfilters 完整配置 Available Plugins https://maven.apache.org/plugins/index.html Maven 是一個開源的軟件構建工具&…