简体   繁体   English

Relay / GraphQL的身份验证和权限

[英]Authentication and privileges on Relay/GraphQL

Facebook does not mention authentication for their GraphQL library. Facebook没有提到他们的GraphQL库的身份验证。

Suppose I have a users table fetchable from GraphQL and I do not wish to disclose users information to anybody who demands it except the logged in user, at what level should I add the authentication layer ? 假设我有一个可以从GraphQL获取的用户表,我不希望向除了登录用户之外的任何需要它的人透露用户信息,我应该在什么级别添加认证层?

At the schema level by mutating a "logged-in" state ? 在模式级别通过改变“登录”状态?

Or maybe by passing extra parameters to the graphql function that currently takes only query and schema ? 或者可能通过将额外的参数传递给当前只接受queryschemagraphql函数?

It's possible to add auth header with token to your GraphQL queries. 可以将带有令牌的auth头添加到GraphQL查询中。

var token = localStorage.getItem('id_token');

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://pathtohost/graphql', {
    headers: {
      Authorization: token
    }
  })
);

This blog post https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.cpmrcqcyt describes 3 types of authentication with Relay. 此博客文章https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.cpmrcqcyt描述了3种使用Relay的身份验证。

1 - based on a token ( https://stackoverflow.com/a/34843562/2628278 ) - This one scales better \\o/ 1 - 基于令牌( https://stackoverflow.com/a/34843562/2628278 ) - 这个更好地扩展\\ o /

2 - based on rootValue ( https://stackoverflow.com/a/36001558/2628278 ) 2 - 基于rootValue( https://stackoverflow.com/a/36001558/2628278

3 - based only in Relay and GraphQL 3 - 仅基于Relay和GraphQL

The problem with the first two approaches is that you need to use non-relay/graphql code to handle this. 前两种方法的问题是您需要使用非中继/ graphql代码来处理这个问题。

The third approach is like this: 第三种方法是这样的:

{
  viewer(token: String) {
    name
  }
}

pass the auth token to viewer, and let graphql handles it 将auth令牌传递给viewer,让graphql处理它

you will need a mutation as well: 你也需要一个突变:

mutation {
  createToken(username: String!, password: String!) {
    token
    error
  }
}

that will return the token or an error. 这将返回令牌或错误。 The token should be stored in a cookie or local storage on web, and on AsyncStorage on React Native 令牌应存储在Web上的cookie或本地存储中,以及React Native上的AsyncStorage

Although it's really unclear in the documentation, in addition to schema and query (or requestString as it's called in the docs), you can also pass a rootValue . 虽然在文档中真的不清楚,除了schemaquery (或在文档中调用的requestString )之外,您还可以传递rootValue That value will be passed to every resolve function in your GraphQL schema, so it's where you want to put any authentication information that is paired with the request. 该值将传递给GraphQL架构中的每个解析函数,因此您可以在其中放置与请求配对的任何身份验证信息。

For example if you call graphql with: 例如,如果您使用以下命令调用graphql

graphql(schema, query, auth, variables)

In your resolve functions you'll have access to auth : 在您的解析功能中,您可以访问auth

async user(auth, args) {
  return await db.users.find(auth, args.id)
}

Another option is to use a Relay Network Layer other than the Default one, such as nodkz/react-relay-network-layer . 另一种选择是使用默认网络层以外的中继网络层,例如nodkz / react-relay-network-layer

This network layer support middlewares, and you can inject an authMiddleware to specify the Auth Token for each Relay request. 此网络层支持中间件,您可以注入authMiddleware为每个中继请求指定Auth Token。 You can also specify what to do if the server fails to authorize the request (ie send user to the login screen). 如果服务器无法授权请求(即将用户发送到登录屏幕),您还可以指定要执行的操作。 See an example of how you can set it up: 查看如何设置它的示例:

import { RelayNetworkLayer, urlMiddleware, authMiddleware } from 'react-relay-network-layer';

const middlewares = [
  urlMiddleware({
    url: () => `${graphqlAPIHost}/dragon/v2/graph`
  }),
  authMiddleware({
    token: () => auth.accessToken(), // Here you retrieve the Auth Access Token
    tokenRefreshPromise: (req) => {
      loginActions.logout(); // Here you specify what to do if the server returns 401
      return req;
    }
  })
];
Relay.injectNetworkLayer(new RelayNetworkLayer(middlewares, { disableBatchQuery: true }));

This will send the auth token in the request headers. 这将在请求标头中发送身份验证令牌。 For more information visit the nodkz/react-relay-network-layer github page. 有关更多信息,请访问nodkz / react-relay-network-layer github页面。

So, On the server side you can check this repo I've created showing how to handle login/logout using GraphQL mutations: https://github.com/shalkam/graphql-login 因此,在服务器端,您可以检查我创建的这个repo,显示如何使用GraphQL突变处理登录/注销: https//github.com/shalkam/graphql-login

It's using passport.js for auth. 它使用passport.js进行身份验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM