Apollo / GraphQL / Prisma“登录”突变不会返回所有用户字段

Posted

技术标签:

【中文标题】Apollo / GraphQL / Prisma“登录”突变不会返回所有用户字段【英文标题】:Apollo / GraphQL / Prisma "Login" Mutation Won't Return All User Fields 【发布时间】:2020-10-09 01:16:56 【问题描述】:

我对 GraphQL / Prisma / Apollo 的世界比较陌生,并且正在开发一个需要登录功能和基于用户权限的访问限制的应用程序。

当我运行我的登录突变时,如果我请求返回用户的“角色”字段,它会失败并且我终其一生都无法弄清楚原因。

如果我对所有用户进行简单查询并请求“角色”字段,则返回没有问题。 同样,如果我对单个用户进行查询并按任何其他字段进行过滤:- id、电子邮件、用户名。

我的应用是这样设置的:

datamodel.graphql(棱镜)

type User 
  id: ID! @id @unique
  name: String!
  email: String! @unique
  username: String! @unique
  password: String!
  roles: [UserRoles!]!


enum UserRoles 
  ADMIN
  USER
  DIRECTOR

schema.graphql(反应/阿波罗)

type User 
  id: ID!
  name: String!
  email: String!
  username: String!
  password: String!
  roles: [UserRoles!]!


enum UserRoles 
  ADMIN
  USER
  DIRECTOR

Mutation.js(解析器前端)

async loginUser(parent, args,  prisma , info) 
    const  username, password  = args.data;
    const user = await prisma.query.user( where:  username  );

    if (!user) 
      throw new Error("Invalid login credentials. Please try again");
    

    const passwordIsMatch = await bcrypt.compare(password, user.password);

    if (!passwordIsMatch) 
      throw new Error("Invalid login credentials. Please try again");
    

    return 
      user,
      token: generateToken(user.id),
    ;
  ,

如果我像这样运行登录突变,它运行良好。

mutation LoginUser($username: String!, $password: String!)
  loginUser(data: 
    username: $username
    password: $password
  ) 
    user 
      id
      name
    
    token
  

但是如果我这样运行它,它会失败并显示“无法为不可为空的字段 User.roles 返回 null”的消息。

mutation LoginUser($username: String!, $password: String!)
  loginUser(data: 
    username: $username
    password: $password
  ) 
    user 
      id
      name
      roles
    
    token
  

关于如何解决这个问题的任何想法?或者我应该等待对此突变的响应,然后对返回的 id 的用户运行查询,然后从中提取“角色”字段?这对我来说似乎有点多余,因为我认为 GraphQL 的一大好处是最大限度地减少 http 请求的数量。

【问题讨论】:

【参考方案1】:

查询失败,因为 roles 字段在您的架构中声明为必需,但您的解析器显然没有为用户返回任何角色。

要通过验证,您需要在 GraphQL 和 Prisma 模式中将字段规范更改为可选(删除 !s):

  roles: [UserRoles]

【讨论】:

嗨,儿子,感谢您的回复。我实际上需要用户角色作为必填字段。即,当创建用户时,他们必须分配一个角色。有没有其他办法解决? @DonMacarthur 如果您需要角色,那么解析器不为该用户返回任何角色实际上违反了您的要求,验证和拒绝错误实际上对您有所帮助。这是您需要解决的真正问题,而不是解决问题。找出原因并确保所有用户都有角色。或者至少检查角色是否为空并返回至少一个默认角色。就像在从解析器返回之前添加这个:if (!user.roles || !user.roles.length) user.roles = ['default']; 正如您所说,用户查询返回角色很好,然后检查您的解析器调用的prisma.query.user;它可能缺少响应中的角色。 您好,我找到了解决方案。我检查了我调用 prisma.query.user 的行,然后添加了我之后的特定字段,即prisma.query.user( where: username , "id name username password email roles");。这暂时有效,但我担心将所有这些字段发送给客户端。我想在后端完成身份验证后,我必须考虑碎片以过滤掉密码。我不知道为什么我必须这样做,因为我尝试使用作为参数传递的“信息”运行相同的查询,但这不起作用。无论如何,再次感谢您的帮助:-)

以上是关于Apollo / GraphQL / Prisma“登录”突变不会返回所有用户字段的主要内容,如果未能解决你的问题,请参考以下文章

React-Apollo-Prisma-Graphql

使用 Prisma 和 Apollo 调用多个 GraphQL 突变的正确方法是啥

Apollo 和 Prisma Graphql 显式模型关系不可查询

Prisma、GraphQL 和 Apollo 中具有突变的数据关系和连接类型

Prisma v2:生成一个 .graphql 文件来编辑?

如何在 Dockerized GraphQL + Postgres 设置中运行 Prisma 迁移?