Интегрируйте стратегию потока кода авторизации OAuth2 для веб-API Spotify в серверное приложение NodeJS с TypeScript и NestJS.

При создании API одной из наиболее важных частей приложения является безопасность и аутентификация его пользователей. Большинство фреймворков предоставляют некоторые рекомендации по реализации различных стратегий аутентификации. NestJS, например, представляет в своей официальной документации стратегию JWT.

Однако одной из широко распространенных стратегий аутентификации является подход OAuth2, обычно используемый со сторонними сервисами, такими как учетные записи Facebook, Google и Spotify, который позволяет использовать существующую учетную запись в этих сервисах для аутентификации пользователя и даже взаимодействия с этими сервисами от имени. аутентифицированного пользователя.

Поскольку официальной документации по интеграции этого типа аутентификации с NestJS не существует, а статьи разработчиков обычно посвящены интеграции с Google и Facebook, в этой статье представлена ​​альтернатива интеграции Spotify Authorization Code Flow с NestJS с использованием промежуточного программного обеспечения аутентификации Passport. наряду со стратегией паспорт-спотифай.

Требования

В этой статье основное внимание уделяется процессу использования стратегии OAuth2 для Spotify, интегрированного с приложением NestJS, поэтому следующие требования считаются выполненными перед процессом, описанным в этой статье:

  • Приложение NestJS загружается со своей базовой структурой. Для этой части достаточно следовать руководству по быстрой настройке в Документации NestJS;
  • Учетная запись Spotify с доступом к панели инструментов разработчика Spotify и приложение, зарегистрированное с его учетными данными CLIENT ID и CLIENT SECRET. Для этой статьи достаточно следовать пошаговой официальной документации о том, как использовать Spotify API.

Если вы не знакомы с потоком кода авторизации OAuth2, ознакомьтесь с руководством, предоставленным документацией Spotify Web API.

Папка авторизации

Когда приложение NestJS готово, необходимо создать auth resource с помощью следующей команды, учитывая, что на машине установлен Nest CLI:

nest g mo auth
nest g s auth --no-spec
nest g co auth --no-spec

Эти команды создают папку auth с базовыми файлами модулей, служб и контроллеров без каких-либо файлов .spec. Когда все на месте, структура папок должна выглядеть так:

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

npm install @nestjs/passport @nestjs/jwt passport passport-jwt passport-spotify
npm install -D @types/passport-jwt @types/passport-spotify

Отныне есть 3 функции, которые должны быть доступны в приложении с точки зрения аутентификации:

  1. Вход пользователей с использованием потока кода авторизации Spotify OAuth2;
  2. Получение информации о пользователе из Spotify и создание JWT;
  3. Использование стратегии JWT, чтобы не было необходимости подключаться к серверу Spotify OAuth2 каждый раз, когда требуется аутентификация пользователя во время сеанса.

Маршруты

Для первой и второй функций, описанных ранее, необходим контроллер с маршрутами /login и /redirect:

Приведенный выше код включает в себя следующее:

  • Оба маршрута, /login и /redirect, защищены настраиваемым сторожем SpotifyOauthGuard, который реализует стратегию passport-spotify, которая будет описана позже;
  • login method/route — это конечная точка, к которой пользователи будут обращаться для инициации аутентификации;
  • Метод spotifyAuthRedirect (маршрут ‘/redirect’) — это URL-адрес, на который служба Spotify OAuth2 будет перенаправлена ​​после успешного входа пользователя в систему;
  • Метод spotifyAuthRedirect: извлекает информацию о пользователе, поступающую от Spotify, расположенного в свойстве req.user — если информации нет, что означает, что аутентификация не была выполнена или не удалась, метод снова перенаправляет запрос на маршрут входа — устанавливает свойство user req в значение undefined (как это будет определено в дальнейшем как полезная нагрузка JWT), генерирует JWT с ним и возвращает информацию о пользователе и токены Spotify, которые могут использоваться приложением для доступа к маршрутам в веб-API Spotify с использованием информации пользователя в зависимости от объемы определены.

Стратегия Spotify OAuth2

При использовании встроенной стратегии паспорта необходимо создать пользовательскую защиту, а также соответствующую ей стратегию. SpotifyOauthGuard — это просто класс, который расширяет AuthGuard класс, поэтому после создания внутри него папки /guards SpotifyOauthGuard должен выглядеть так:

Кроме того, стратегия с именем spotify должна быть создана в папке /strategies:

Приведенный выше код отвечает за подключение к службе Spotify OAuth2 и управление перенаправлением в приложение. Процесс:

  • Класс SpotifyOauthStrategy расширяет PassportStrategy, используя стратегию, предоставляемую библиотекой passport-spotify, и называет его spotify, чтобы SpotifyOauthGuard мог его идентифицировать;
  • Метод конструктора вызывает метод Strategy constructor passport-spotify с использованием метода _24, передавая учетные данные приложения Spotify CLIENT_ID и CLIENT_SECRET (сохраненные в переменных .env, поскольку они не должны быть опубликованы), лучше описано здесь, URL-адрес обратного вызова, который тот же маршрут, определенный в auth.controller.ts, '/redirect', и области действия, необходимые приложению для взаимодействия с информацией пользователя;
  • Метод super также имеет функцию обратного вызова, которая будет вызываться, как только процесс входа пользователя завершится успешно, и до того, как он будет перенаправлен в приложение. Эта функция добавляет к запросу, который будет сделан для маршрута ‘/redirect’, следующие свойства: user (содержащий информацию о профиле пользователя) и authInfo (содержащий информацию refreshToken, accessToken и expires_in).

Перенаправление и генерация JWT

Как только стратегия будет реализована, пользователь будет перенаправлен на URL-адрес «/redirect», и в auth.controller.ts (представленном ранее) метод spotifyAuthRedirect перехватит объект req, извлечет свойства user и authInfo и передаст user в authService. . С информацией о пользователе метод login в классе AuthService отвечает за создание JWT. auth.service.ts должен выглядеть так:

Наконец, в auth.service.ts маршрут /redirect возвращает объект, содержащий authInfo и свойства пользователя, а также заголовок Authentication, установленный на «Bearer», объединенный с JWT.

Стратегия JWT

Эта часть аутентификации в основном описана в официальной документации NestJS. Для этой части необходимо определить в ваших .env vars JWT_SECRET, которая представляет собой строку, которая используется для генерации и шифрования/дешифрования JWT, которые генерирует приложение, и не должна раскрываться публично. Подобно стратегии Spotify, необходимо создать класс JwtAuthGuard, который расширяет встроенный паспорт AuthGuard вместе с соответствующим именем jwt. Внутри папки /guards создайте файл jwt-auth.guard.ts следующим образом:

И соответствующая стратегия внутри папки /strategies должна выглядеть так:

Приведенный выше код выполняется, когда маршрут украшен JwtAuthGuard. Метод super() извлекает JWT, предоставленный запросом, на защищенный маршрут, расшифровывает его с помощью предоставленного JWT_SECRET и вставляет свойство user в объект req, содержащий информацию, которая ранее была вставлена ​​в полезную нагрузку JWT.

Важно подчеркнуть, что вставленное свойство user отличается от того, что spotify-strategy вставляет в объект req, и именно по этой причине в методе spotifyAuthRedirect свойство req.user устанавливается в значение undefined перед входом в систему с помощью стратегии jwt.

Теперь любой маршрут аутентификации может быть украшен JwtAuthGuard следующим образом:

Конфигурации AuthModule и AppModule

Когда все готово, пришло время настроить создание всех модулей. Класс AuthModule должен выглядеть так:

Файл auth.module.ts определяет всех поставщиков ресурса аутентификации и регистрирует JWT_SECRET во время создания экземпляра JwtModule, а также время его истечения, здесь определенное как 3600 с (1 час).

Кроме того, AppModule должен выглядеть так:

app.module.ts создает экземпляры всех модулей приложения, включая ConfigModule, который необходим для использования всех переменных env, описанных в процессе.

Окончательное состояние папок и файлов приложения должно выглядеть так:

Заключение

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

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