漏洞赏金猎人笔记-GraphQL-III

简介: 前面介绍了query、mutation这两种类型的操作,今天将要介绍最后一种类型的操作:subscription



前言


前面介绍了query、mutation这两种类型的操作,今天将要介绍最后一种类型的操作:subscription

这里对这三种类型的操作做一个简单的总结:

  • query 查询:获取数据,比如查找,CRUD 中的 R
  • mutation 变更:对数据进行变更,比如增加、删除、修改,CRUD 中的 CUD
  • substription 订阅:当数据发生更改,进行消息推送

此外,这三种类型都需要由解析函数 Resolver 来提供数据,比如

query {
  hi
}

那么同名的解析函数resolver(一般也是写在后端)应该是这样的

Query: {
  hi (parent, args, context, info) {
    return ...
  }
}

解析函数接受四个参数,分别为

  • parent:当前上一个解析函数的返回值
  • args:查询中传入的参数
  • context:提供给所有解析器的上下文信息
  • info:一个保存与当前查询相关的字段特定信息以及 schema 详细信息的值

解析函数的返回值可以是一个具体的值,也可以是 Promise 或 Promise 数组。

此外还需要知道Schema这个文件:

它定义了字段的类型、数据的结构,描述了接口数据请求的规则,当我们进行一些错误的查询的时候 GraphQL 引擎会负责告诉我们哪里有问题,和详细的错误信息,对开发调试十分友好。

Schema一般使用一个简单的强类型模式语法,称为模式描述语言(Schema Definition Language, SDL)

# src/schema.graphql
# Query 入口
type Query {
    hello: String
    users: [User]!
    user(id: String): [User]!
}
# Mutation 入口
type Mutation {
    createUser(id: ID!, name: String!, email: String!, age: Int,gender: Gender): User!
    updateUser(id: ID!, name: String, email: String, age: Int, gender: Gender): User!
    deleteUser(id: ID!): User
}
# Subscription 入口
type Subscription {
    subsUser(id: ID!): User
}
type User implements UserInterface {
    id: ID!
    name: String!
    age: Int
    gender: Gender
    email: String!
}
# 枚举类型
enum Gender {
    MAN
    WOMAN
}
# 接口类型
interface UserInterface {
    id: ID!
    name: String!
    age: Int
    gender: Gender
}

这里的 Schema 文件(这个文件一般写在后端)从 Query、Mutation、Subscription 入口开始定义了各个对象类型或标量类型,这些字段的类型也可能是其他的对象类型或标量类型,组成一个树形的结构,而用户在向服务端发送请求的时候,沿着这个树选择一个或多个分支就可以获取多组信息。


正文


这里主要通过一个实例来理解,先看个图来理解大体上的一个逻辑:

26.png

通过订阅这样的一个操作在服务端注册了了一个订阅查询,如果服务端有对应的更新,就会触发这个所订阅的查询,最后会在客户端实时更新。

下面通过一个例子来理解一下Subscription:

当前端发起订阅请求之后,如果后端发现数据改变,可以给前端推送实时信息。

Schema文件:

# Subscription 入口
type Subscription {
    subsUser(id: ID!): User
}
type User {
    id: ID!
    name: String!
    age: Int
    email: String!
}

对应resolver:

import Db from'../db'
const { PubSub, withFilter } = require('apollo-server')
const pubsub = new PubSub()
const USER_UPDATE_CHANNEL = 'USER_UPDATE'
exportdefault {
    Mutation: {
        updateUser: (parent, { id, name, email, age }) => Db.user({ id })
            .then(existUser => {
                if (!existUser)
                    thrownewError('没有这个id的人')
                return existUser
            })
            .then(() => Db.updateUser({ id, name, email, age }))
            .then(user => {
                pubsub.publish(USER_UPDATE_CHANNEL, { subsUser: user })
                return user
            })
    },
    Subscription: {
        subsUser: {
            subscribe: withFilter(
                (parent, { id }) => pubsub.asyncIterator(USER_UPDATE_CHANNEL),
                (payload, variables) => payload.subsUser.id === variables.id
            ),
            resolve: (payload, variables) => {
                console.log('🚢 接收到数据:', payload)
            }
        }
    }
}

这里的 pubsub 是 apollo-server 里负责订阅和发布的类,它在接受订阅时提供一个异步迭代器,在后端觉得需要发布订阅的时候向前端发布 payload。withFilter 的作用是过滤掉不需要的订阅消息

我们发布一个订阅请求:

# 请求
subscription subsUser($id: ID!) {
  subsUser(id: $id) {
    id
    name
    age
    email
  }
}
# 参数
{ "id": "2" }

用刚刚的数据更新操作来进行一次数据的更改,然后我们将获取到并打印出 pubsub.publish 发布的 payload,这样就完成了数据订阅。

全文完结。


参考

https://www.apollographql.com/docs/react/data/subscriptions/

https://dgraph.io/blog/post/how-does-graphql-subscription/

https://github.com/apollographql/docs-examples/blob/main/apollo-server/v3/subscriptions-graphql-ws/src/index.ts#L14


目录
相关文章
|
3月前
|
安全 JavaScript 前端开发
赏金猎人必学站点(梯外)
赏金猎人必学站点(梯外)
|
6月前
|
SQL 安全 测试技术
花无涯带你走进黑客世界之好用的渗透测试神器
隔着屏幕的祝福送给大家,祝大家端午安康,我就不群发骚扰了,看到的都好运 -。- 安全研究者对网站或者应用程序进行渗透测试而不用任何自动化工具似乎已越来越难。 花无涯带你走进黑客世界 2 学习渗透技术
|
SQL Oracle 安全
PortSwigger之SQL注入实验室笔记(一)
PortSwigger之SQL注入实验室笔记
217 0
PortSwigger之SQL注入实验室笔记(一)
|
SQL 安全 Oracle
PortSwigger之SQL注入实验室笔记(二)
PortSwigger之SQL注入实验室笔记
282 0
PortSwigger之SQL注入实验室笔记(二)
|
安全 API 网络架构
漏洞赏金猎人笔记-GraphQL-II
上一节我们学习了GraphQL的一些基础知识,本文继续深入研究,从对比的角度来切入,方便读者理解. Mutation 在GraphQL中,只有两种类型的操作,就是queries 和 mutations. 如果说query类似于REST中的GET操作,那么Mutation就好比REST中的DELETE, PUT,PATCH方法,笔者用一句简单的话来概括一下: query用来查询服务端的数据,而mutation用来修改服务端的数据
197 0
漏洞赏金猎人笔记-GraphQL-II
|
JSON 安全 前端开发
漏洞赏金猎人笔记-GraphQL-I
为了方便理解,这里从一个例子出发来理解GraphQL 通常情况下,当你想获取有关书籍和作者的详细信息时,用REST API的风格写为:
192 0
漏洞赏金猎人笔记-GraphQL-I
|
数据采集 域名解析 XML
漏洞猎人赏金笔记-如何编写Bug Bounty自动化脚本
前言 本文原文作者为@pry0cc,本文主要是对原文相关内容的提炼以及笔记,出于易读性考虑,笔者对很多地方做了一定量的注释或者删改(因为原文中的脚本存在一定问题)。 本文主要讲解的是经典的自动化信息搜集以及数据处理和漏洞扫描的流程.
412 0
漏洞猎人赏金笔记-如何编写Bug Bounty自动化脚本
|
安全 Shell
赏金猎人系列-如何测试sso相关的漏洞
前言 前面写过一篇有关sso绕过的相关文章:你所不知道的sso绕过tips,而本文主要总结的是sso漏洞相对比较系统的的测试方法,限于篇幅,这里会分为两篇来叙述,今天为第一篇;
222 0
|
XML 安全 Go
赏金猎人系列-如何测试sso相关的漏洞(II)
前言 本文承接前文:赏金猎人系列-如何测试sso相关的漏洞,继续梳理sso漏洞相关的测试方法.
129 0
|
Web App开发 安全 Java
Facebook 被曝雇用公司抹黑 TikTok;Spring 承认 RCE 大漏洞;Chrome 100 发布 | 思否周刊
Facebook 被曝雇用公司抹黑 TikTok;Spring 承认 RCE 大漏洞;Chrome 100 发布 | 思否周刊
161 0

热门文章

最新文章

相关实验场景

更多