Graphql 盾返回未授权允许的突变

问题描述 投票:0回答:3

我正在尝试使用 apollo-server-express 实现 GraphQL API。我想通过 graphql-shield 中间件管理权限,但在允许执行突变方面遇到问题。我的目标是进行基于 JWT 的身份验证,但允许对未经身份验证的用户执行注册/登录突变所需的一些查询/突变。我正在使用默认的

allow
规则。但是当我尝试运行登录突变时,我收到 未授权! 错误。我不知道为什么会这样。该规则适用于查询。

谢谢您的回答。

服务器

import express from "express";
import cors from "cors";
import { ApolloServer, makeExecutableSchema } from "apollo-server-express";
import config from "./config";
import mockResolver from "./resolvers/mockResolver";
import typeDefs from "./graphql/typeDefs";
import { applyMiddleware } from "graphql-middleware";
import permissions from "./graphql/permissions";

const app = express();
app.use(cors());

const server = new ApolloServer({
  schema: applyMiddleware(
    makeExecutableSchema({ typeDefs, resolvers: mockResolver }),
    permissions
  ),
  playground: true,
  introspection: true,
});

server.applyMiddleware({ app, path: "/graphql" });
app.listen(config.PORT, () =>
  console.log("Server listening at http://localhost:%s", config.PORT)
);

类型定义

import { gql } from "apollo-server";

const typeDefs = gql`
  type User {
    id: Int!
    email: String!
    password: String!
  }

  type LoginResponse {
    id: String
    email: String
    token: String
  }

  type Query {
    user(id: Int!): User
    users: [User]
  }

  type Mutation {
    login(email: String!, password: String!): LoginResponse
  }
`;

权限

import { shield, allow } from "graphql-shield";

const permissions = shield({
  Query: {
    users: allow,
  },
  Mutation: {
    login: allow,
  },
});

export default permissions;
javascript node.js express graphql apollo-server
3个回答
4
投票
const permissions = shield({
  Query: {
    users: allow,
  },
  Mutation: {
    login: allow,
  },
});    

const permissions = shield({
  Query: {
    users: allow,
  },
  Mutation: {
    login: allow,
  },
},
{
  debug: true
});

并追踪错误消息。


1
投票

我同意另一个答案会起作用,但除了(或而不是)

allowExternalErrors
之外,您还可以使用
debug

请参阅文档了解两者的解释。

正如那里所述:

默认情况下,屏蔽可确保内部数据不会暴露给客户端(如果不应该)。因此,执行期间抛出的所有错误都会解析为“未授权”!如果没有使用错误包装器另外指定,则会出现错误消息。可以通过将allowExternalErrors选项设置为true来关闭此功能。

这意味着默认情况下,即使发生不同的错误,Shield 也会报告 401 错误。这意味着您将被引导相信您存在身份验证问题,而实际上是其他问题。即使在您的实时网站上,因其他错误而获得身份验证错误可能也不是一个好主意。

因此,包含选项

allowExternalErrors: true
将使您的错误消息更加清晰:

const permissions = shield({
  Query: {
    users: allow,
  },
  Mutation: {
    login: allow,
  },
},
{
  allowExternalErrors: true
});

如果需要,您也可以在开发中将

debug
设置为true。


0
投票

以上两者都是正确的,但如果您想限制可能意外暴露给客户端的数据,您可以同时保留

allowExternalErrors: false
debug: false
并根据具体情况进行处理。为了实现这一点,您需要返回任何故意创建的错误,而不是抛出它们。这样,GraphQL Shield 就可以智能地处理这些错误,因为它知道返回的错误旨在过滤到客户端。

return new Error('This should make it passed the Shield');

throw new Error('This will return a "Not Authorised!" message')

根据他们的文档:

要向客户端返回自定义错误消息,您可以返回错误而不是抛出错误。这样,Shield 就知道这不是错误,而是受控的设计决策。除了返回错误之外,您还可以返回表示自定义错误消息的字符串

https://the-guild.dev/graphql/shield/docs/errors

© www.soinside.com 2019 - 2024. All rights reserved.