当前位置: 首页 > 知识库问答 >
问题:

来自客户端的错误数据通过GraphQL验证

云锦
2023-03-14

我已经用React和Apollo客户端在NestJS服务器上用GraphQL API制作了简单的CRUD应用程序。

我有一个简单的突变:

schema.gql:

type Mutation {
  createUser(input: CreateUserInput!): User! // CreateUserInput type you can see in user.input.ts below
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): User!
}
user.input.ts:

import { InputType, Field } from "@nestjs/graphql";
import { EmailScalar } from "../email.scalar-type";

@InputType()
export class CreateUserInput {
    // EmailScalar is a custom Scalar GraphQL Type that i took from the internet and it worked well
    @Field(() => EmailScalar)
    readonly email: string;
    @Field()
    readonly name: string;
}

“EmailScalar”类型主要检查“email”输入是否具有*@*.*格式

它不能通过验证(因为电子邮件类型工作正常)

但当从客户端发送的查询通过验证时:

NestJS服务器日志(来自下面的代码)

users.resolver.ts:

@Mutation(() => User)
async createUser(@Args('input') input: CreateUserInput) { // Type from user.input.ts
   Logger.log(input); // log from screenshot, so if it's here it passed validation
   return this.usersService.create(input); // usersService makes requests to MongoDB
}
App.tsx:

...

// CreateUserInput class is not imported to App.tsx (it is at server part) but it seems to be fine with it
const ADD_USER = gql`
  mutation AddMutation($input: CreateUserInput!) {
    createUser(input: $input) {
      id
      name
      email
    }
  }
`

function App(props: any) {
  const { loading, error, data } = useQuery(GET_USERS);

  const [addUser] = useMutation(
    ADD_USER,
    {
      update: (cache: any, { data: { createUser } }: any) => {
        const { users } = cache.readQuery({ query: GET_USERS });
        cache.writeQuery({
          query: GET_USERS,
          data: {
            users: [createUser, ...users],
          },
        })
      }
    }
  );

...

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return <UserTable users={data.users} addUser={addUser} updateUser={updateUser} deleteUser={deleteUser} />;
}

以前从未使用过NestJS、Apollo、React或GraphQL,所以我有点迷路了。

完整代码:https://github.com/n238635/nest-react-crud-test

共有1个答案

阳凌
2023-03-14

这就是如何定义自定义标量的方法:

parseValue(value: string): string {
  return value;
}

serialize(value: string): string {
  return value;
}

parseLiteral(ast: ValueNode): string {
  if (ast.kind !== Kind.STRING) {
    throw new GraphQLError('Query error: Can only parse strings got a: ' + ast.kind, [ast]);
  }

  // Regex taken from: http://stackoverflow.com/a/46181/761555
  var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
  if (!re.test(ast.value)) {
    throw new GraphQLError('Query error: Not a valid Email', [ast]);
  }

  return ast.value;
}

在分析查询内部的文字值(即用双引号包装的文字字符串)时调用parseliteral。分析变量值时调用parsevalue。当您的客户端发送查询时,它将该值作为变量发送,而不是作为文字值发送。因此使用parsevalue而不是parseliteral。但是parsevalue不执行任何类型的验证--您只是原样返回值。您需要在这两种方法中实现验证逻辑。

实现serialize方法也是一个好主意,这样您的标量可以同时用于输入和响应验证。

 类似资料:
  • 问题内容: 我有以下代码: 现在,第二个http调用失败,出现401访问被拒绝错误。不同的REST客户端(firefox插件)可以正确地从服务器获取详细信息,因此我知道服务器端没有错。我是否需要传递某种会话字符串或上次请求中获得的内容? 问题答案: 好的。我已经解决了。我只需要创建一个饼干罐。 我很惊讶golang http req / client类没有默认处理此问题。 我必须使用的代码是: 然

  • 当我在主机服务器的浏览器上运行这个应用程序时,我成功地获得了一个json对象(它不是我期望的json,但这是另一个问题)。但是,当我试图访问远程客户端上的站点时,我会得到一个403错误,指向我试图检索响应时的位置。有什么想法吗?

  • 我只是在我的服务器上设置SSL证书。我很确定他们是对的。当转到在浏览器中,页面正确加载,地址栏中显示绿色锁。 在Firefox上发帖子 如果我在Java客户机上发布同样的帖子,我会得到以下错误: 在我的服务器上,我已经把CA_ROOT证书放在JAVA.../jre/lib/Security/cacert密钥库中。 这是我在Java客户端发布的代码。 请注意:这不是一个自己签署的证书。它是由一个认证

  • 问题内容: 我正在寻找GraphQL 的Java 客户端 库。两者均用于Java中的服务器到服务器通信。没有android,没有javascript …只是java。Apollo是最接近的答案,似乎仅适用于Android,而不适用于纯Java应用程序。有很多关于用Java构建服务器的例子,没有关于客户端的例子。任何想法?谢谢! 问题答案: 有几个可用的客户,都采用不同的方法。 Apollo And

  • 下面是AWS Ec2中Mongo的副本设置,io1(10000 iops)和r4。8XL码 1个主节点、1个辅助节点、1个仲裁节点 我们有2种类型的应用程序写入/读取Mongo,几乎数据接近2亿 现在,我们从Mongo获得readtimeout/sockettimeour,而application1在Mongo上几乎没有写操作,而application2在Mongo上执行大量写操作 Applica

  • 我们试图对cadence设置进行基准测试(目前在2个EC2实例上运行:m5a.xlarge ),发现了许多cadence客户端错误: cadence_service:cadence_matching,操作:历史记录重新记录活动任务已启动