Аутентификация и привилегии на Relay/GraphQL
Facebook не упоминает аутентификацию для своей библиотеки GraphQL.
Предположим, что у меня есть таблица пользователей, выбранная из GraphQL, и я не хочу раскрывать информацию о пользователях любому, кто ее требует, кроме зарегистрированного пользователя, на каком уровне я должен добавить уровень аутентификации?
На уровне схемы, изменяя состояние "вошедшего в систему"?
Или, может быть, передав дополнительные параметры функции graphql
, которая в настоящее время принимает только query
и schema
?
Ответы
Ответ 1
Можно добавить заголовок auth с токеном в ваши запросы GraphQL.
var token = localStorage.getItem('id_token');
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://pathtohost/graphql', {
headers: {
Authorization: token
}
})
);
Ответ 2
Это сообщение в блоге https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.cpmrcqcyt описывает три типа аутентификации с реле.
1 - на основе токена (fooobar.com/questions/385363/...) - Этот режим масштабируется лучше \o/
2 - на основе rootValue (fooobar.com/questions/385363/...)
3 - только в Relay и GraphQL
Проблема с первыми двумя подходами заключается в том, что для этого вам нужно использовать код non-relay/graphql.
Третий подход выглядит следующим образом:
{
viewer(token: String) {
name
}
}
передать токен auth для просмотра, и пусть graphql обрабатывает его
вам понадобится также мутация:
mutation {
createToken(username: String!, password: String!) {
token
error
}
}
который вернет токен или ошибку.
Маркер должен храниться в файле cookie или локальном хранилище в Интернете и на AsyncStorage
на React Native
Ответ 3
Хотя это действительно неясно в документации, помимо schema
и query
(или requestString
, как он называется в документах), вы также можете передать rootValue
. Это значение будет передано каждой функции разрешения в вашей схеме GraphQL, поэтому там, где вы хотите поместить любую информацию проверки подлинности, связанную с запросом.
Например, если вы вызываете graphql
с помощью:
graphql(schema, query, auth, variables)
В ваших функциях решения вы получите доступ к auth
:
async user(auth, args) {
return await db.users.find(auth, args.id)
}
Ответ 4
Другой вариант - использовать уровень сети ретрансляции, отличный от значения по умолчанию, например nodkz/react-relay-network-layer.
Этот сетевой уровень поддерживает middlewares, и вы можете ввести authMiddleware, чтобы указать токен Auth для каждого запроса на ретрансляцию. Вы также можете указать, что делать, если сервер не авторизует запрос (т.е. Отправляет пользователя на экран входа в систему). См. Пример того, как вы можете настроить его:
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 }));
Это отправит токен auth в заголовках запроса. Для получения дополнительной информации посетите страницу nodkz/react-relay-network-layer github.