Авторизация в GraphQL

Пара функций, которые мне очень нравятся в GraphQL, - это строгая система типов и самодокументирующийся API, использующий GraphiQL и игровую площадку. Нет необходимости тратить лишнее время и силы на написание документации по API. Благодаря талантливым ребятам из Apollo и Prisma, внедрение GraphQL-сервера производственного уровня стало проще простого.

Однако для большинства серверных программ API требуется аутентификация и авторизация. В GraphQL есть много способов добиться этого.

В этой статье я расскажу об одном из таких подходов к реализации авторизации.

Для реализации логики авторизации воспользуемся директивой GraphQL. Поскольку директивы GraphQL могут быть прикреплены к полю, у нас может быть авторизация на уровне поля. См. Фрагмент кода ниже:

Запрос getPosts не требует аутентифицированного пользователя. С другой стороны, мутация createPost строго требует аутентифицированного пользователя.

Директива isAuthenticated, прикрепленная к createPost, проверяет токен аутентификации и на основе флага strict выдает ошибку GraphQL в случае сбоя авторизации.

Мы можем реализовать эту директиву с помощью библиотеки graphql-tools:

Последний шаг - настроить сервер для использования нашей директивы. Мы будем использовать graphql-yoga для настройки сервера.

Вывод

Использование директивы GraphQL для обработки авторизации имеет несколько преимуществ:

Разделение озабоченности

Наш код обработки token живет в директиве. Таким образом, преобразователи могут просто использовать полностью гидратированный пользовательский объект через context.currentUser. При необходимости мы можем расширить директиву для поддержки авторизации на основе ролей, просто приняв другой аргумент @isAuthenticated(strict: true, roles: ['ADMIN'])

Документация

Директива @isAuthenticated указывается рядом с полями в schema.graphql, поэтому легко увидеть, для каких API требуется аутентифицированный пользователь. Также мы обновляем field.description символом 🔑! Так что это будет видно в GraphiQL или playground пользовательском интерфейсе. Мы также можем задокументировать роли, необходимые для доступа к API, и так далее.

Соглашаться? Не согласны? Вопросы? Просто дайте мне знать здесь, в комментариях. И если вам понравилась эта статья, подумайте о том, чтобы опубликовать ее и поделиться ею!