13

現在、DefaultNetworkLayer に設定されたカスタム ヘッダーを使用して、リレーの外部で認証を処理しています。それは好ましい方法ですか、リレーでそれを行う方法はありますか? リレーでサインアップ機能を実装しようとしたときに行き詰まりました: リレーには次の構成があります: FIELDS_CHANGE、NODE_DELETE、RANGE_ADD、RANGE_DELETE。したがって、ここで適用できるのは RANGE_ADD だけですが、そのための親と接続が必要です。これは、新しく作成されたユーザーにはありません....

4

3 に答える 3

16

私のプロジェクトでもこの問題が発生しました。これが私がそれを処理した方法です。そのフィールドでユーザースキーマを作成しました

export var GraphQLUser = new GraphQLObjectType({
  name: 'User',
  fields: {
  id: globalIdField('User'), //this id is an immutable string that never change.
  userID: {
    type: GraphQLString,
    description: 'the database user\'s id',
  },
  name: {
    type: GraphQLString,
    description: 'the name of the user',
  },
  mail: {
    type: GraphQLString,
    description: 'the mail of the user',
  }
})

次に、ルートスキーマのユーザーフィールドがどのように見えるかを示します

var GraphQLRoot = new GraphQLObjectType({
  user: {
  type: new GraphQLNonNull(GraphQLUser),
  description: 'the user',
  resolve: (root, {id}, {rootValue}) => co(function*() {
    var user = yield getUser(rootValue);
    return user;
  })
}

ルートスキーマで、次のように実装した getUser 関数を要求します。これが主なハックです!

const logID = 'qldfjbe2434RZRFeerg'; // random logID that will  remain the same forever for any user logged in, this is the id I use for my FIELD_CHANGE mutation client side

export function getUser(rootValue) {
  //IF there is no userID cookie field, no-one is logged in
  if (!rootValue.cookies.get('userID')) return {
    name: '',
    mail: '',
    id: logID
  };
  return co(function*() {
    var user =  yield getDatabaseUserByID(rootValue.cookies.get('userID'));
    user.userID = user.id;
    user.id = logID // change the id field with default immutable logID to handle FIELD_CHANGE mutation
    return user;
  })
}

これがloginMutationクライアント側です

export default class LoginMutation extends Relay.Mutation {
  static fragments = {
    user: () => Relay.QL`
     fragment on User {
      id,
      mail
    }`,
  }
  getMutation() {
    return Relay.QL`mutation{Login}`;
  }

  getVariables() {
    return {
      mail: this.props.credentials.pseudo,
      password: this.props.credentials.password,
      id: this.props.user.id
    };
  }
  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        user: this.props.user.id,
      }
    }];
  }
  getOptimisticResponse() {
    return {
      mail: this.props.credentials.pseudo,
      id: this.props.user.id
    };
  }
  getFatQuery() {
    return Relay.QL`
    fragment on LoginPayload {
      user {
        userID,
        mail,
        name,
      }
    }
    `;
  }

次に、ここに loginMutation サーバー側があります

export var LoginMutation = mutationWithClientMutationId({
  name: 'Login',
  inputFields: {
    mail: {
      type: new GraphQLNonNull(GraphQLString)
    },
    password: {
      type: new GraphQLNonNull(GraphQLString)
     },
     id: {
       type: new GraphQLNonNull(GraphQLString)
    }
  },
  outputFields: {
    user: {
      type: GraphQLUser,
      resolve: (newUser) => newUser
    }
  },
  mutateAndGetPayload: (credentials, {rootValue}) => co(function*() {
    var newUser = yield getUserByCredentials(credentials, rootValue);
    //don't forget to fill your cookie with the new userID (database id)
    rootValue.cookies.set('userID', user.userID);
    return newUser;
  })
});

ほら!あなたの質問に答えるために、私は FIELD_CHANGE ミューテーションを使用し、ログインしているユーザーに関係なく同じ ID を共有しました。正しいユーザーを取得するために使用される実際の ID は、実際には userID です。私のプロジェクトでは問題なく動作します。ここで見ることができますRelay-Graphql-repo

PS: Cookie を受け入れるには、networkLayer に追加する必要があります。

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('/graphql', {
  credentials: 'same-origin'
  })
);
于 2016-01-24T10:23:19.513 に答える
1

Relay は意図的に認証メカニズムに依存しないため、ネットワーク層を介してカスタム ヘッダーを使用することが適切です。

ログイン後の応答を処理する方法については、その時点でページ全体の更新またはリダイレクトをトリガーするのがおそらく最善です。アイテム)。閲覧者のアイデンティティがアイテムの可視性に非常に大きな影響を与える可能性があることを考えると、正しい/堅牢な動作を維持するには、完全なリセットが必要です。

于 2015-09-12T22:10:08.737 に答える
0

ドキュメント化されていない構成タイプが存在しますが、これはそのユース ケースに適しているように見えます: https://github.com/facebook/relay/issues/237

于 2015-09-21T02:05:42.453 に答える