Это руководство было написано Абхиджитом Сингхом и опубликовано в рамках Hasura Technical Writer Program — инициативы, которая поддерживает авторов, которые пишут руководства и учебные пособия для Hasura GraphQL Engine с открытым исходным кодом.

Введение

В этом руководстве я покажу вам, как использовать Hasura GraphQL Engine и React для создания клона веб-приложения Instagram. Окончательный код размещается здесь. Смотрите живую демоверсию приложения здесь.

Приложение будет иметь следующие функции:

  • Пользователи могут создавать учетные записи (используя аутентификацию Auth0)
  • Аутентифицированные пользователи могут загружать новые сообщения
  • Аутентифицированные пользователи могут лайкать сообщения
  • Аутентифицированные пользователи могут следить за учетными записями пользователей
  • Отображать сообщения в ленте
  • Обновления в реальном времени, когда другие пользователи голосуют за сообщение, создают новое сообщение или следят за профилем пользователя (с использованием управления состоянием реагирования и обновления кеша apollo).

Начальная настройка

Давайте начнем с создания внешнего интерфейса нашего приложения с помощью React.

Чтобы быстро приступить к работе, мы создадим базовое приложение реакции без настройки сборки, используя create-react-app. Выполните следующие команды в терминале:

$ npx create-react-app instagram-clone
$ cd instagram-clone
$ npm start

Примечание. npx — это средство запуска пакетов npm. Обычно это используется для временной загрузки и запуска пакета или для пробных версий. create-react-app — это пакет npm, который предполагается запускать только один раз в жизненном цикле проекта. Поэтому предпочтительнее использовать npx для установки и запуска за один шаг. (источник)

Сервер запустится, и вы увидите экран приветствия (как показано ниже) на http://localhost:3000.

Чтобы улучшить структуру проекта, давайте создадим два каталога, оба внутри папки src. Первый называется components и будет содержать все наши компоненты React. Второй styles для всех CSS-файлов, которые вы будете использовать.

Переместите необходимые файлы jsx и css в соответствующие каталоги и измените ссылки на эти файлы в index.js и App.js соответственно. Ваша структура каталогов должна выглядеть так:

├── node_modules
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.test.js
│ ├── components
│ │ └── App.js
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── styles
│   ├── App.css
│   └── index.css
└── README.md

Я буду использовать пакет react-bootstrap для стиля. Установите пакет, используя:

$ npm install react-bootstrap bootstrap

Обязательно добавьте ссылки CDN на таблицы стилей в /public/index.html. Скопируйте ссылки здесь.

Также установите клиент GraphQL react-apollo, используя следующую команду:

$ npm install apollo-boost apollo-link-context @apollo/react-hooks @apollo/react-hoc graphql

Клиент Apollo помогает вам использовать GraphQL API из внешнего интерфейса.

Далее мы настроим серверную часть с помощью Hasura GraphQL Engine и Postgres.

См. это руководство, чтобы быстро начать работу с движком Hasura GraphQL и Postgres, работающими на Heroku, с развертыванием в один клик.

Настройка серверной части

Структура нашей базы данных Postgres:

type Post {
    id - integer, primary key
    caption - text
    url - text
    created_at - timestamp with time zone
    user_id - text
}
 
type User {
    name - text
    last_seen - timestamp with time zone
    avatar - text
    email - text
    id - text, primary key
}

type Like {
    id - integer, primary key
    user_id - text
    post_id - integer
}

type Follow {
    id - integer, primary key
     follower_id - text
    following_id - text
}

Создание таблиц

Создайте следующие таблицы: User таблица

Таблица Post ( id имеет тип integer(autoincrement)):

Добавьте ограничение внешнего ключа из столбца user_id в User.id . Установите Update и Delete Нарушение как restrict.

Таблица Like ( id имеет тип integer(autoincrement)):

Таблица Follow ( id имеет тип integer(autoincrement)):

Создайте отношение object, перейдя в раздел таблиц отношений. Эти отношения помогут нам запрашивать данные в одном запросе, а также выполнять различные виды агрегатных функций, таких как получение количества сообщений для каждого пользователя. См. эту ссылку для создания отношений через внешний ключ в хасуре. Нам просто нужны следующие соотношения.

Теперь мы настроим разрешения для таблиц, чтобы только зарегистрированные пользователи могли делать определенные вещи. Настройте разрешения, как показано ниже:

См. Основы управления доступом, если вы не очень хорошо знакомы с контролем доступа и тем, как он работает в хасуре.

Чтобы сделать это менее сложным, я дал все разрешения на уровне строк без каких-либо проверок и на уровне столбцов как все столбцы и запросы агрегации (используемые для подсчета количества баллов за сообщение).

Использование Auth0 JWT для аутентификации

На следующем рисунке кратко показано, как работает аутентификация JWT. Здесь необходимо настроить сервер приложений (наш бэкенд) для проверки того, что входящие JWT создаются сервером аутентификации (Auth0).(источник)

Мы используем Auth0 в качестве сервера аутентификации. Он создаст JWT и перейдет в наше приложение для реагирования. Затем, используя клиент apollo, мы отправим auth_token (в нашем случае access_token) на наш бэкэнд (сервер приложений), то есть на Hasura GraphQL Engine. Hasura необходимо настроить для проверки того, что входящий JWT создается сервером аутентификации Auth0.

Давайте начнем с Auth0, используя @apollo/react-hooks и @auth0/auth0-spa-js. Мы должны выполнить следующие шаги:

Интеграция Auth0 JWT с Hasura: см. это руководство по интеграции Auth0 JWT с Hasura и получите JWK (ключ для проверки входящего JWT). В панели управления Auth0 установите Allowed Callback URLs, Allowed Web Origins, Allowed Logout URLs на http://localhost:3000 и сохраните изменения.

Вам также может понадобиться отключить OIDC Conformant в Auth0 > Applications > Your_app > Settings > Advanced Settings. Когда у вас есть ключ, следующим шагом будет активация режима JWT в Hasura. Перейдите на панель инструментов heroku, выберите наше приложение и перейдите в настройки. Здесь вы можете увидеть некоторые Config Vars, которые мы сейчас настроим. Добавьте переменные конфигурации следующим образом:

Здесь клавиша HASURA_GRAPHQL_ADMIN_SECRET для работы режима JWT. Поместите ключ в переменную HASURA_GRAPHQL_JWT_SECRETenvironment. После того, как вы добавите это, конечные точки GraphQL можно будет запрашивать только с использованием заголовка Authorization или заголовка X-Hasura-Admin-Secret.

Наконец, установите для HASURA_GRAPHQL_UNAUTHORIZED_ROLE значение anonymous, потому что мы разрешаем неавторизованным пользователям читать некоторые данные.

Неавторизованная роль: используется, когда ключ доступа не отправляется в режиме только ключа доступа или заголовок «Авторизация» отсутствует в режиме JWT. Пример: anonymous. Теперь, когда заголовок «Авторизация» отсутствует, роль запроса по умолчанию будет «анонимной».

Следующий шаг — добавить правила в наше приложение Auth0. Мы добавим еще 2 правила в приложение Auth0, как показано ниже:

Здесь мы заменяем idToken на accessToken. По сути, auth0 предоставляет различные типы токенов, а auth0-spa-js больше не предоставляет idToken, поэтому мы будем использовать accessToken.

Обновление. Начиная с версии 1.2.0 auth0-spa-js необработанное значение idToken предоставляется с помощью метода getIdTokenClaims.

Подробнее о токенах здесь.

Новый SPA SDK использует только предоставление кода авторизации + PKCE (больше не неявное предоставление). Таким образом, мы должны использовать accessTokens вместо idTokens. (См. эту ветку).

Добавьте еще одно правило для синхронизации нашей базы данных postgres и пользователей Auth0:

Измените admin_secret и url соответственно. Теперь всякий раз, когда новый пользователь регистрируется или входит в систему, наша база данных hasura postgres будет автоматически обновляться, чтобы хранить информацию о пользователе в нашей таблице users. Смотрите это для более подробной информации.

Примечание. Здесь мы просто делаем почтовый запрос с изменениями graphql, и у нас есть x-hasura-admin-secret в заголовке, поэтому входящий запрос имеет полный доступ для изменения базы данных.

Нам также нужно создать собственный API в Auth0 Dashboard > APIs, который будет указывать на наш Hasura GraphQl API. Создайте новый API, как показано ниже, и дайте ему любое имя. Измените Identifier на конечную точку graphql.

Теперь, когда у нас есть наш бэкэнд и настройка Auth0, мы можем приступить к созданию приложения React. Перейдите к 2-й части этой серии, чтобы узнать, как это сделать.

Об авторе

Абхиджит Сингх учится на последнем курсе UG по специальности Информатика и инженерия в IIIT Kalyani. Он работал в области разработки полного стека, Android, глубокого обучения, машинного обучения и НЛП. Он активно участвует в соревнованиях по программированию и интересуется решением алгоритмических задач. Он энтузиаст стартапов и в свободное время играет в настольный теннис и на гитаре.

Первоначально опубликовано на https://blog.hasura.io 6 сентября 2019 г.