1

首先感谢您阅读本文,我花了最后一天的时间来解决这个我根本无法弄清楚的错误。我之前有它工作过,但由于某种原因它停止了。基本上,所有服务都按预期独立工作。但是,一旦我尝试引用另一个(假设我正在使用配置文件服务并想从帐户服务中提取电子邮件),它只会返回 null。没有错误信息,什么都没有。我已经添加了重要的代码片段,但如果您想查看整个代码库,请告诉我,我会将其推送到 github。

帐户类型定义:

import { gql } from 'apollo-server';

const typeDefs = gql`
  # SCALARS
  """
  An ISO 8601-encoded UTC date string...
  """
  scalar DateTime
  # OBJECTS
  """
  An account is an Auth0 user that provides authentication details.
  """
  type Account @key(fields: "id") {
    "The unique Auth0 ID associated with the account."
    id: ID!
    "The date and time the account was created."
    createdAt: DateTime!
    "The email associated with the account (must be unique)."
    email: String
    "Whether the account is blocked."
    isBlocked: Boolean
    "Whether the account has a moderator role."
    isModerator: Boolean
  }

帐户解析器:

 Account: {
    __resolveReference(reference, { dataSources }, info) {
      return dataSources.accountsAPI.getAccountById(reference.id);
    },
    id(account, args, context, info) {
      return account.user_id;
    },
    createdAt(account, args, context, info) {
      return account.created_at;
    },
    isModerator(account, args, context, info) {
      return (
        account.app_metadata &&
        account.app_metadata.roles &&
        account.app_metadata.roles.includes('moderator')
      );
    },
    isBlocked(account, args, context, info) {
      return account.blocked;
    },
  },

配置文件类型定义:

      extend type Account @key(fields: "id") {
        id: ID! @external
        "Metadata about the user that owns the account."
        profile: Profile
      }
  type Profile @key(fields: "id") {
    "The unique MongoDB document ID of the user's profile."
    id: ID!
    "The Auth0 account tied to this profile."
    account: Account!
    "The URL of the user's avatar."
    avatar: String
    "A short bio or description about the user (max. 256 characters)."
    description: String
    "Other users that the user follows."
    following(
      first: Int
      after: String
      last: Int
      before: String
      orderBy: ProfileOrderByInput
    ): ProfileConnection
    "The full name of the user."
    fullName: String
    "The URL of the user's GitHub page."
    githubUrl: String
    "The user's pinned GitHub repositories and gists."
    pinnedItems: [PinnableItem]
    "The unique username of the user."
    username: String!
    "Whether the currently logged in user follows this profile."
    viewerIsFollowing: Boolean
  }

轮廓解析器:

Profile: {
    account(profile, args, context, info) {
      return { __typename: 'Account', id: profile.account_id };
    },
}
4

1 回答 1

0

在写这篇文章时,我意识到问题出在哪里,所以我会把它贴在这里,这样你们就不必浪费时间了。我还不明白为什么,我会尽快跟进,但由于某种原因,我拥有的权限(使用 grahpql-shield)。打破一切,在创建联合服务时将其注释掉后,它神奇地开始工作,对于那些好奇的人,这是我的权限。

账户许可

import { and, or, rule, shield } from 'graphql-shield';

import getPermissions from '../../lib/getPermissions';

const canReadAnyAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('read:any_account');
});

const canReadOwnAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
  (parent, { id }, { user }, info) => user.sub === id,
);

const isEditingOwnAccount = rule()(
  (parent, { where: { id } }, { user }, info) => user.sub === id,
);

const permissions = shield(
  {
    Query: {
      account: or(
        and(canReadAnyAccount, isEditingOwnAccount),
        canReadAnyAccount,
      ),
      accounts: canReadAnyAccount,
    },
    Mutation: {
      changeAccountBlockedStatus: canBlockAccount,
      changeAccountModeratorRole: canPromoteAccount,
      deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
      updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
    },
  },
  { debug: process.env.NODE_ENV === 'development' },
);

export default permissions;

配置文件权限:

import { and, or, rule, shield } from 'graphql-shield';

import getPermissions from '../../lib/getPermissions';

const canReadAnyAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('read:any_account');
});

const canReadOwnAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('read:own_account');
});
const canEditOwnAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('edit:own_account');
});
const canBlockAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('block:any_account');
});
const canPromoteAccount = rule()((parent, args, { user }, info) => {
  const userPermissions = getPermissions(user);

  return userPermissions && userPermissions.includes('promote:any_account');
});
const isReadingOwnAccount = rule()(
  (parent, { id }, { user }, info) => user.sub === id,
);

const isEditingOwnAccount = rule()(
  (parent, { where: { id } }, { user }, info) => user.sub === id,
);

const permissions = shield(
  {
    Query: {
      account: or(
        and(canReadAnyAccount, isEditingOwnAccount),
        canReadAnyAccount,
      ),
      accounts: canReadAnyAccount,
    },
    Mutation: {
      changeAccountBlockedStatus: canBlockAccount,
      changeAccountModeratorRole: canPromoteAccount,
      deleteAccount: and(canEditOwnAccount, isEditingOwnAccount),
      updateAccount: and(canEditOwnAccount, isEditingOwnAccount),
    },
  },
  { debug: process.env.NODE_ENV === 'development' },
);

export default permissions;

我还要感谢 8 bit-press 的 Mandi,因为她是我通过她那本很棒的书学习 graphql 的原因。这里或那里可能存在一些错误(尚不确定,因为我容易犯错误,如果不是,这可能是一个错误,并且对其他阅读本书的人有用)但我当然建议任何想要学习阿波罗的人检查出来 https://8bit.press/book/advanced-graphql

于 2020-12-18T16:16:01.043 回答