Подтвердить что ты не робот

Как структурировать аутентифицированные запросы с помощью GraphQL?

Я подумывал написать API, который выполняет следующие действия:

  • Пользователи регистрации и входа в систему, которые предоставляют пользователю токен аутентификации
  • Создание карт (пример данных: { name: "Quotes", attributes: ["quote", "author"] })
  • Создание элементов карты (пример данных: { quote: "...", author: "..." })

Я бы построил несколько запросов следующим образом:

// return the name and id of all the user maps
maps(authToken="…") {
  name,
  id
}

// return all the items of a single map
maps(authToken="…") {
  map(name="Quotes") {
    items
  }
}

// OR by using the map_id
maps(authToken="…") {
  map(id="…") {
    items
  }
}

Итак, мой вопрос: правильно ли это или мне нужно структурировать его по-другому?

4b9b3361

Ответ 1

Я бы рекомендовал создать аутентификацию вне самого GraphQL и позволить вашей логике схемы обрабатывать авторизацию. Например, если вы используете модуль express-graphql NPM, вы можете проверить свои файлы cookie или HTTP Basic Auth или какой-либо механизм, который вы хотите использовать для получения вашего токена аутентификации, а затем передать свой аутентифицированный объект просмотра через схему через rootValue, который доступен на каждом уровне во время разрешения запроса:

app.use('/graphql', (request, response, next) => {
  const viewer = getViewerFromRequest(); // You provide this.
  const options = {
    rootValue: {
      viewer,
    },
    schema,
  };

  return graphqlHTTP(request => options)(request, response, next);
});

И затем внутри схемы вы имеете доступ к вашему rootValue и можете использовать ее для целей контроля доступа и авторизации:

resolve: (parent, args, {rootValue}) => {
  const viewer = {rootValue};

  // Code that uses viewer here...
}

Обратите внимание, что по сравнению с graphql v0.5.0, подпись resolve изменилась и третий параметр "context" был вставлен в позицию 3 в аргументе список. Этот параметр подходит для передачи токена аутентификации или аналогичного:

resolve: (parent, args, authToken, {rootValue}) => {
  // Code that uses the auth token here...
}

Ответ 2

Я предложил подход, который структурирует резольверов как состав меньших функций, чтобы помочь в решении этой точной проблемы. Вы можете увидеть полный ответ здесь: Как проверить разрешения и другие условия в запросе GraphQL?.

Основная идея заключается в том, что если вы структурируете свои резольверы в виде небольших функций, которые составлены вместе, вы можете сложить различные механизмы авторизации/аутентификации друг над другом и выбросить ошибку в первом, которая не выполняется. Это поможет сохранить ваш код в чистоте, проверке и повторном использовании:)

Также да, контекст resolver - отличное место для хранения информации аутентификации, а также других полезных свойств, которые могут потребоваться для использования в ваших распознавателях.

Счастливый взлом!