Sign with apple php

Внедряем Sign in with Apple — систему авторизации от Apple

Этим летом на конференции WWDC 2019 Apple представила собственную систему авторизации Sign in with Apple и сделала ее обязательной для всех приложений в App Store, которые используют вход через соцсети. Исключение составляют образовательные, корпоративные, правительственные и бизнес-приложения, использующие собственную авторизацию. К Sign in with Apple Apple сделала качественную документацию, и в этой статье мы на примере ЦИАН расскажем, как внедрить ее в свой сервис.

Настраиваем Apple Developer Account

Работа по интеграции начинается с настройки аккаунта разработчика. Сначала нужно включить опцию Sign In with Apple для вашего App ID. Для этого заходим в список идентификаторов в Apple Developer Account, выбираем необходимый App ID и включаем для него опцию Sign In with Apple.

Теперь настраиваем Service ID — уникальный идентификатор web-приложения, который понадобится для обращения к Sign in with Apple API. Всего на один App ID можно создать до 5 Service ID. Для этого нажимаем кнопку создания идентификаторов, выбираем Service ID, заполняем необходимые поля и нажимаем Edit в поле Sign In With Apple. Откроется форма, где выбираем правильный Primary App ID, указываем веб-домен и перечислям URL для редиректа после успешного логина. Надо учитывать, что можно ввести только 10 Return URLs:

Для сохранения нажимаем Save, Continue и Register. Да, при любых изменениях конфигурации необходимо нажимать все три кнопки, иначе изменения не вступят в силу.

Теперь в списке Service ID выбираем созданный идентификатор и опять нажимаем Edit в поле Sign In With Apple. В открывшемся окне у поля с веб-адресом видим две новые кнопки:

Этот файл необходим, чтобы Apple верифицировала ваш ресурс. Скачиваем его и размещаем его на своем ресурсе. Сразу у нас этот финт не сработал: когда наши админы добавили файл, то по указанному url срабатывал редирект (302) на файл, лежащий в другом месте, и Apple его не верифицировал. Тогда пришлось размещать файл по прямому доступу по URL (200). После того как Apple успешно проверит файл, рядом с доменом загорится зеленая галочка:

Из раздела идентификаторов переходим в раздел Keys и создаем новый ключ. Для этого ставим галочку Sign In with Apple и нажимаем сначала Configure, чтобы проверить App ID, затем Continue:

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

Читайте также:  Розыгрыш айфон 12 вилсаком

Для пользователей у Sign In with Apple есть бонус: она позволяет предоставить фейковый e-mail, на который можно писать только с доверенных адресов. В этом случае нужна дополнительная настройка. Открываем раздел More, нажимаем Configure в разделе Sign In with Apple и вписываем свой URL:

Добавляем кнопку Sign In with Apple в iOS-приложение

ЦИАН работает на трех платформах: iOS, Android, Web. Для iOS есть нативное SDK, поэтому авторизация будет выглядеть следующим образом:

Чтобы добавить в iOS-приложение Sign in with Apple, добавляем кнопку ASAuthorizationAppleIDButton и вешаем на нее обработчик нажатия:

Кроме ASAuthorizationAppleIDProvider, обратите внимание еще на ASAuthorizationPasswordProvider, который позволяет получать связки «логин-пароль» из Keychain.

Теперь мы реализуем ASAuthorizationControllerPresentationContextProviding:

Создаем делегат ASAuthorizationControllerDelegate, который сообщает об успехе или ошибке:

Полученный authorizationCode мы отправляем на сервер и ждем ответа от бэкенда об успешности авторизации в нашей системе.

Реализуем Sign in with Apple для web и Android

Внезапно, для Android и Web Apple не предоставляет SDK, поэтому в обоих случаях нужно открыть страницу авторизации от Apple и процесс будет иным:

URL для страницы авторизации выглядит следующим образом:

Рассмотрим его параметры:

  • client_id — Service ID, который регистрировали выше.
  • redirect_uri — URI, куда пользователь перенаправляется после успешной аутентификации через AppleID. Этот URI мы указывали выше при настройке Apple Developer.
  • state — идентификатор сессии пользователя, который Apple вернет при вызове redirect_uri, чтобы мы могли проверить отправителя. Правило генерации этого параметра можете придумать самостоятельно, например, рандомную строку.
  • scope — в этом параметре указывается, какая нужна информация от пользователя. Например, name, email или сразу оба, как в примере выше.
  • response_type — этот параметр указывает, в каком виде нужен ответ. Он может быть code или id_token. Если выбрать id_token, то его нужно уточнить параметром response_mode, в котором можно указать query, fragment и form_post.

После успешной двухфакторной аутентификации через appleID Apple вызовет указанный redirect_uri и передаст параметры state и code:

В параметре code передается одноразовый код аутентификации пользователя, который действует в течение 5 минут. В параметре state — идентификатор сессии, отправленный при создании формы авторизации, а в параметре user — данные пользователя.

Получение данных

На всех клиентах, чтобы сохранить данные пользователя, нужно получить от Apple access_token. Для этого сначала запрашиваем authorization_code:

  • в client_id указывается созданный для web-приложений ServiceID и AppID для iOS-приложения.
  • code — мы получили выше после редиректа или передали с iOS-клиента
  • в параметре grant_type передаем цель получения токена: авторизация (authorization_code) или продление токена (refresh_token)
  • в параметре client_secret — JSON Web Tokens на основе секретного ключа, полученного при регистрации приложения.

Создать JSON Web Tokens можно на Python:

Если все прошло успешно, то в ответе придут такие параметры:

Ура, вот и access_token. Вместе с ним приходит refresh_token, которым можно обновить при необходимости access_token.

Информация о пользователе хранится в поле id_token, но его нужно декодировать:

Apple_public_key — это публичный ключ, который можно получить по ссылке.

После декодирования получаем:

Email передается только один раз, когда пользователь впервые авторизуется в вашем сервисе через Sign in with Apple. В следующий раз Apple передаст эти данные только в том случае, если пользователь самостоятельно отвяжет ваше приложение. Этим авторизация от Apple отличается от других сервисов, где данные можно получить через API, и мы не нашли информацию о том, что они планируют реализовать что-то подобное.

Читайте также:  Если iphone не распознается

В этом ответе нам нужны параметры sub, который передается каждый раз, и email, поэтому мы сохраняем их у себя в системе и сообщаем клиенту о успешной авторизации. PROFIT.

Источник

README

  • Generating an Apple authorisation link to use with your Sign-In button
  • Verifying and decoding Apple JWTs
  • Verifying Apple Authorisation Codes and exchanging them with Apple’s API for access/refresh tokens
  • Automatic fetching of Apple’s public keys and generating of client secrets.

Contents

Installation

Configuration

Config Key Description
clientId Also referred to as Service ID. This can be found here.
privateKey The is required to generate the Client Secret which is used to verify Authorisation Codes. You can pass a string or the path to the key file. The key can be created and downloaded here.
keyId The ID associated with the above privateKey . This should be available on the page where you downloaded your private key.
teamId This is usually found in the top right corner under your name in the Apple Developer area.
redirectUri This is the web page users will be redirect to after (un)successful sign-in. This address must be HTTPS and cannot be localhost. See FAQ for localhost workaround.
defaultScopes These are the scopes you would like returned from Apple. Apple only supports name and email .
apiKeysEndpoint (optional) URL containing Apple’s public key in JWK format. Unless you have a reason to change this the default should be fine.
apiTokenEndpoint (optional) The endpoint used to verify Authorisation Codes. Unless you have a reason to change this the default should be fine.
apiAuthEndpoint (optional) The authorisation URL used to build the URL users will sign in on. Unless you have a reason to change this the default should be fine.

See below for examples of passing config values.

Usage & Examples

Verifying an Authorisation Code and retrieving the access/refresh tokens

See AuthCodeVerifyResponse for all available methods.

Verifying and Decoding Apple JWTs

See JwtVerifyResponse for all available methods.

Example Decoded JWT

Generating an Authorisation URL for your Sign-In button

You can also use Apple’s JS SDK to show Apple’s pre-styled button. Using the above method is for when you would like more control over the style of the button.

End-to-End Sign-In page & Return Page

your-sign-in-page.php

your-return-page.php

FAQ & Troubleshooting

I’m developing on localhost, how do I get the redirect URI to work correctly?

Unfortunately even during testing Apple doesn’t allow using localhost or non-HTTPS redirect URLs. To get around this you can use a browser extension like Requestly to intercept the redirect and direct it to your localhost URL. You can also use a secure tunneling tool like Ngrok.

I’m getting an invalid_request — Invalid redirect_uri error

This usually occurs if your Redirect URI isn’t configured for use in the Apple Developer area. Or the URI may be localhost or non-HTTPS.

I’m getting an Invalid Grant error when verifying my Authorisation Code

This usually means your token is expired or malformed. Apple’s tokens have a 10 minute expiry, after this you will need to generate a new token.

How do I get the user’s name from Apple?

Apple will only send the user’s name the first time the user registers on your app. The payload is POSTed to the Redirect URI along with the authorisation code and the JWT token. The format will look like this:

I would like the Sign-In to happen in a pop-up window

You can use Apple’s JS SDK to achieve this.

I’m getting an Error processing private key error?

If you’re passing the key as a string ensure the formatting is correct. An example of the correct way to pass the key:

Can the request to fetch Apple’s public key be cached?

Yes, you can use Guzzle Middleware to handle caching. You can also inject your own cache enabled client which implements ClientInterface.

Источник

How to verify code from «Sign In with Apple»?

I’m trying to verify the code I got from the «Sign In with Apple» service on my Redirect Uri. I used the information from the documentation to create the post data and generate the «client_secret».

My functions to generate the «client_secret» can be found below:

My variables in this example:

$kid is my identifier for my private key. In this example it is JYJ5GS7N9K. I got the identifier from here https://developer.apple.com/account/resources/authkeys/list

$iss is my team identifier from my developer account. In this example it is WGL33ABCD6.

$sub is the same value as «client_id». My «client_id» in this example is «dev.hanashi.sign-in-with-apple». I got the client id from the app identifiers here: https://developer.apple.com/account/resources/identifiers/list

$key is my generated private key by developer account. The key has format like this:

This is the php code to make the request:

I get now the response <"error":"invalid_client">from the apple server. What am I doing wrong? Could it be that I’m generating the JWT token wrong?

4 Answers 4

The problem for me was that I forgot to verify my domain under the Service Id section of the Apple dev portal.

The website doesn’t verify automatically, you have to click the verify button and get a green tick next to the domain to be sure. After this, I had no more invalid_client issues.

Update 2020.07

As the flow was changed, you just have to add the Domain and the Communication Email to:

Certificates, Identifiers & Profiles > More > Configure

I had this error several times. Here are the causes I could find:

  • Improper Domain Verification and invalid redirect_uri
  • Client ID is not correct: your client ID could be incorrect.
  • JWT encoder is not working properly: maybe it doesn’t support the ES256 algorithm?
  • Request type: for /auth/authorize, you need to use x-www-form-urlencode, oherwise you get invalid_client errors.

When I solved these problems, I started to get invalid_grant error. Here were the steps I had been doing:

  • I created client_secret via JWT
  • I navigated to https://appleid.apple.com/auth/authorize?response_type=code&state=abcdefg&client_id=com.company.apple-sign-in-abcd&scope=openid&redirect_uri=https://app.com/redirect_uri manually on web browser,
  • authorized
  • it redirected back to backend url (which gave 404 because it was not deployed yet).
  • I copied the code argument in the url bar when
  • With the copied code , I POSTeed the https://appleid.apple.com/auth/token endpoint with x-www-form-urlencoded arguments:
    • code
    • client_id
    • client_secret
    • redirect_uri
    • grant_type=»authorization_code»

If you lose a few seconds, code gets invalidated and you’ll get invalid_grant error. If you copy and paste immediately within second, you’ll get your response:

The next step would be decoding id_token with Apple’s public key.

Источник

Читайте также:  Звуки животных для айфона
Оцените статью