Приветствую, уважаемый читатель!
Пришла пора внедрить систему аутентификации от Apple в проект на Django DRF, ведь система входа от Google была реализована давно и по идее проблем не должно было возникнуть, но как оказалось, у Apple есть свои определённые интересные и не очень особенности, о которых я напишу ниже.
Почитав документацию, покопавшись в интернете на различных ресурсах, как русскоязычных так и англоязычных, я пришёл к выводу, что для такого мощного инструмента WEB разработки как Django DRF, нет внятного руководства по внедрению Sign‑in with Apple в проект, так что бы оно работало как говориться «из коробки».
В этой статье я хотел бы попытаться исправить ситуацию, а так же, возможно, многим упростить жизнь при внедрении такой полезной опции как Sign-in with Apple в проект написанный на Django REST framework.
А теперь по порядку:
Для Google sign-in был использован пакет https://github.com/wagnerdelima/drf-social-oauth2. На установке и настройке пакета нет смысла заострять внимание, ведь в руководстве всё подробно описано, а так же имеется пример авторизации "по Google".
Пожалуй стоит отметить, что строка выпуска токена авторизации для Google sign-in будет выглядеть так:
curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&client_secret=<django-oauth-generated-client_secret>&backend=google-oauth2&token=<google_token>" http://localhost:8000/auth/convert-token
В случае с Apple sign in, всё остаётся так же, меняем только название backend на
backend=apple-id
и ссылку запроса наhttps://yourdomanname/api/auth/convert-token
(путь к вашей конечной точке), в соответствии с этой библиотекой social-auth-core, а документация находится тут.Получаем необходимые учетные данные от Apple.
Примечание: Для подключения Apple sign-in требуется учетная запись Apple Developer.
С учетом этого, вот шаги, которые вам нужно предпринять, чтобы настроить Apple Login.
Настройка учетной записи разработчика Apple.
Есть четыре вещи, необходимые для интеграции Sign-in with Apple в ваше приложение.
Service ID
Bundle ID
Private key
Team ID
Шаги, описанные ниже, позволят вам получить эти данные, приступим.
Сначала необходимо создать идентификатор приложения по адресу
https://developer.apple.com/account/resources/certificates/list
или можно просто нажать тут ,затем перейдите во вкладкуIdentifiers
щелкните+
рядом сIdentifiers
Выбираем «App IDs» и нажимаем «continue».
Выбираем опцию «App» и нажимаем «continue».
Добавляем описание вашего приложения в поле
description
. Затем добавляем свой идентификатор пакета Bundle ID в формате: com.domainname.appnameПереходим в «Capabilities» и включаем Sign In with Apple .
Нажимаем на кнопку «edit», выберите
Enable as a primary App ID
, а затем жмём «save».Нажимаем «continue». Проверяем всю введенную информацию и, если все верно, жмём на
Register
.
Теперь необходимо создать идентификатор службы.
Переходим на ту же страницу, что и раньше, но теперь выбираем
Service IDs
из выпадающего списка справа.Identifiers
щелкаем знак+
рядом сIdentifiers
.Задаём Description и Identifier.
Устанавливаем галочку на
Signin with apple
и, нажимаемConfigure
, выбираем Primary App ID.Вам будет предложено выбрать ваш Primary App ID (выберите приложение которое мы создали в пункте выше).
Затем добавляем домен вашего приложения, щёлкнем на
+
рядом сWebsite URLs
.В поле Domains and Subdomains вводим название вашего домена, для которого необходима авторизация по AppleID. Тут нужно отметить, что в это поле необходимо вводить только название домена без
https://
в формате sub.domainname.com, иначе вы потом будете получать ошибку, при авторизации.В поле Return URLs добавляем URL-адрес, который выглядит так https://sub.domainname.com/auth, он должен совпадать с адресом, по которому
react app
или любое другое приложение со стороны "фронта", будет запрашивать данные от Apple.
Примечание: В отличии от Google, Apple не позволяет использовать записи формата
http://localhost:8000
в Return URLs, поэтому подключить всё это "дело" к локальному хосту и протестировать не получится, Apple вообще не допускает использование приложение без SSL сертификата, то есть толькоhttps://
.Сохраняем все.
Проверяем правильность введённой информации и нажимаем
Register
.
Вернёмся на страницу и перейдём на вкладку
Keys
, нажимаем+
чтобы добавить новый ключ (или перейдите на страницу регистрации нового ключа ).Добавим имя для вашего ключа Key Name.
Установим галочку на
Signin with apple
и нажмёмConfigure
.Выбираем Primary App ID, как в пункте 2 и нажимаем
save
.Проверим правильность введённой информации и жмём
Register
.Скачиваем сгенерированный сертификат.
Настало время настроить наше приложение на Django DRF, для использования с AppleID.
Открываем наш проект, а в частности файл
settings.py
и изменяем его следующим образом:AUTHENTICATION_BACKENDS = [ # Google OAuth2 'social_core.backends.google.GoogleOAuth2', #Apple OAuth2 'social_core.backends.apple.AppleIdAuth', #drf‑social‑oauth2 'drf_social_oauth2.backends.DjangoOAuth2', #Django 'django.contrib.auth.backends.ModelBackend', ]
Дальше необходимо добавить данные, полученные от Apple:
# Apple OAuth2 SOCIAL_AUTH_APPLE_ID_CLIENT = 'com.domainname.service' # Берём в Services IDs со страницы IDENTIFIER, который мы создали в предыдущем пункте SOCIAL_AUTH_APPLE_ID_TEAM = 'K2232113' # Team ID, можно посмотреть на странице https://developer.apple.com/account/#/membership, прокручиваем вниз до Membership details, смотрим наш Team ID SOCIAL_AUTH_APPLE_ID_KEY = 'Y2P99J3N81K' # Ваш Key ID, смотрим на странице созданного нами ключа, из прошлого пункта SOCIAL_AUTH_APPLE_ID_SECRET = ””” Откройте свой файл ключа Apple, в любом текстовом редакторе, и поместите сюда всё содержимое, включая ‑--‑BEGIN PRIVATE KEY‑--- ‑--‑END PRIVATE KEY‑--‑””” SOCIAL_AUTH_APPLE_ID_SCOPE = ['email', 'name'] SOCIAL_AUTH_APPLE_ID_EMAIL_AS_USERNAME = True # Если нужно использовать email в качестве имени пользователя
Примечание: Проходя все эти эти шаги с настройкой Django DRF приложения, я подразумеваю, что у Вас уже установлены все пакеты из первого пункта, миграции все выполнены, а необходимые импорты и настройки добавлены, в соответствии с руководством этого пакета, а так же созданы
client_id
иclient_secret.
Формирование ссылки запроса в Apple.
Пройдя все подготовительные этапы настало время сформировать
"верный"
запрос в Apple, для того, что бы получить id_token авторизации от Apple и передать его на сервер, для завершения авторизации в вашем WEB-приложении.Примечание: Пусть вас не смущает название id_token, при изучении документации по API от Apple, на деле это
JSON Web Token
подписанный Apple и содержащий информацию о пользователе.Для получения
id_token
отApple
можно воспользоваться этой библиотекой, если ваш frontend написан на React.Сама ссылка выпуска id_token должна выглядеть так:
https://appleid.apple.com/auth/authorize?client_id=com.domainname.service&redirect_uri=https://sub.domainname.com/auth&state=&response_type=code id_token&response_mode=form_post&scope=email
Примечание:
client_id
иredirect_uri
мы задали в пункте 2, когда создавалиService ID.
Так же в запросе обязательно указывайтеscope=email
, иначе при декодировании id_token вернётся ошибка, что email не обнаружен (Apple просто не поместит эти данные в id_token). Но если вы в последствии измените ссылку и добавитеscope=email
, то для пользователя, который уже пытался совершить авторизацию ничего не изменится, его email не будет находиться в id_token до тех пор, пока он не удалит приложение в личном кабинете Apple и не зайдёт по новой, используя верную ссылку для выпуска id_token.Вот пример того, что мы получаем от
Apple:
Авторизация на стороне сервера Django DRF.
Вот мы подошли к завершающему этапу, к тому ради чего мы производили все предыдущие манипуляции. Как я и говорил в пункте 1, нам всего лишь необходимо отправить
POST
запрос по адресуhttps://yourdomanname/api/auth/convert-token
, ответом которого будет являтьсяBearer Token
, который мы будем использовать при каждом обращении к нашему API.Строка для выпуска
Bearer Token
на стороне сервера будет формироваться по следующему принципу:grant_type=convert_token&client_id=<django-oauth-generated-client_id>&client_secret=<django-oauth-generated-client_secret>&backend=apple-id&token=<id_token>
Примечание:
Media type
запроса должен бытьapplication/x-www-form-urlencoded
Вот пример того, что мы получим, после успешного прохождения авторизации на стороне сервера:
Надеюсь, этот материал окажется для кого-то полезным. Спасибо, что дочитали текст до конца!