Top.Mail.Ru
Авторизация без SDK для iOS | VK ID - сервис авторизации
VK ID auth service logo

Авторизация без SDK для iOS

Важно. Если вы интегрируете VK ID без SDK, способы авторизации по One Tap, с помощью шторки авторизации или через 3 в 1 будут недоступны.
Не рекомендуем использовать подключение авторизации VK ID через открытие WebView — в этом случае авторизация может работать некорректно. Вместо него используйте подключение авторизации через открытие в браузере, о котором рассказывается в этой статье, или с помощью SDK.
Начиная с версии VK ID SDK 2.2.0, необходимо явно указывать доступы phone, email, чтобы получать эти данные. Подробнее
Перед настройкой авторизации убедитесь, что в кабинете сервиса авторизации VK ID приложение создано и настроено. Чтобы подключить авторизацию VK ID в приложении:
  1. Настройте подключение по ссылке.
  2. Получите код авторизации с помощью «перехватывания» редиректа.
  3. Обменяйте код на токен.
Когда будете создавать UI своего приложения, убедитесь что кнопка входа через VK ID соответствует требованиям к дизайну.

Настройка Info.plist

Чтобы пользователь с активной сессией в приложении VK мог быстро авторизоваться в сервисе с интегрированным VK ID без повторного ввода данных, сервис взаимодействует с клиентом ВКонтакте или другим официальным приложением VK на устройстве пользователя. Приложение VK выступает провайдером авторизации.
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>vkauthorize-silent</string>
</array>
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>auth_callback</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>vk7915193</string> // Вместо 7915193 подставьте ID вашего приложения.
        </array>
    </dict>
</array>
Сервис взаимодействует с провайдерами авторизации через Universal links. При настройке приложения в кабинете сервиса авторизации VK ID укажите Universal link, по которой провайдер авторизации откроет ваше приложение. Добавьте поддержку Universal links в приложение.

Шаг 1. Настройка подключения по ссылке

На базе Proof Key for Code Exchange (PKCE) реализуйте безопасное получение кода авторизации. Для тестирования рекомендуем генерировать code_verifier и code_challenge с помощью сервиса Online PKCE Generator Tool. Когда у вас будет код авторизации, сформируйте ссылку, по которой будет открываться авторизация в браузере.
let url = "https://id.vk.ru/authorize?state=abracadabra&response_type=code&code_challenge=VT6yRsqMDL8EgEfcGmtWVaaLzTw5KcuKBoGEmfDBJaw&code_challenge_method=S256&client_id=7915193&redirect_uri=vk7915193://vk.ru/blank.html&prompt=login&scope=phone%20email"

let session = ASWebAuthenticationSession(
    url: url,
    callbackURLScheme: "vk7915193" // Идентификатор вашего приложения, например 7915193.
) { [weak self] callbackUrl, error in
    guard let self = self else {
        return
    }
    self.session = nil
    self.handleCallback(callbackUrl, error) // Обработка url, на который произошел редирект.
}
self.session = session
session.start()

Описание параметров

НазваниеОписание
client_idИдентификатор вашего приложения
redirect_uriАдрес, куда будет перенаправлен пользователь после авторизации. Например vk7915193://vk.ru/service.html, где 7915193 — идентификатор вашего приложения. Должен в точности совпадать с тем адресом, который был указан в настройках приложения
stateПроизвольная строка. Проверяется на шаге 2
code_challengeЗначение code_verifier, преобразованное с помощью code_challenge_method и закодированное в base64. Порядок преобразований: BASE64-ENCODE(SHA256(codeVerifier)) RFC-7636 Code Challenge
code_challenge_methodМетод шифрования для генерации code_challenge на основе code_verifier, константа. Всегда принимает значение S256
response_typeТип ответа авторизации. В нашем случае равен code
promptПараметр позволяет изменить способ прохождения авторизации, по умолчанию пустое значение. Однако мы рекоммендуем прописать значение login — так, пользователю всегда будет предлагаться пройти процедуру аутентификации, даже если пользователь уже залогинен в VK ID.
scopeСписок прав доступа, которые нужны приложению. Если параметр не указан, то берётся минимальное значение прав доступа по умолчанию для приложений — vkid.personal_info. В примере выше мы указали доступы к email, phone.

Шаг 2. Обработка редиректа

После авторизации в браузере или в приложении провайдера вы получите URL со следующими параметрами:
НазваниеОписание
device_idЗашифрованный идентификатор устройства
stateПроизвольная строка, переданная на шаге 1
codeКод авторизации
typeТип кода авторизации. В нашем случае code_v2
Проверьте, что state из полученного редиректа совпадает со state из первого шага. Таким образом можно убедиться в том, что это ответ на ваш запрос.

Шаг 2.1 «Перехватывание» редиректа

После авторизации в браузере «перехватите» редирект на redirect_uri, который указали на первом шаге:
vk7915193://vk.ru/blank.html?device_id=generatedencrypteddeviceid123&state=abracadabra&code=vk2.a.FmLgF_...&type=code_v2
После авторизации в провайдере «перехватите» редирект, который указали на первом шаге, или Deep link вида:
vk7915193://?code=vk2.a.FmLgF_...&device_id=generatedencrypteddeviceid123&state=abracadabra&type=code_v2&vkconnect_auth_provider_method=external_auth
Затем добавьте обработчик ссылки при возврате в ваше приложение из провайдера авторизации. Для этого в AppDelegate внесите изменения:
func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
      //  Обработчик url.
}
Работа с UIScene Если ваше приложение использует UIScene, то реализуйте следующий метод из UISceneDelegate:
func scene(
    _ scene: UIScene,
    openURLContexts URLContexts: Set<UIOpenURLContext>
) {
    URLContexts.forEach { ctx in
        //  Добавьте обработчик ctx.url.
    }
}
Работа с SwiftUI Если вы используете SwiftUI, то реализуйте onOpenURL:
var body: some Scene {
    WindowGroup {
        ContentView()
            .onOpenURL { url in
                //  Добавьте обработчик url.
            }
    }
}

Шаг 3. Получение Access token

Обменяйте code на access_token, refresh_token с помощью POST-запроса.

Пример запроса

curl --location 'https://id.vk.ru/oauth2/auth?grant_type=authorization_code&redirect_uri=vk7915193%3A%2F%2Fvk.ru%2Fblank.html&client_id=7915193&device_id=generatedencrypteddeviceid123&state=abracadabracodeexchange&code_verifier=TMqwHtKeYrAz42vNmy5KsxePTYt--KS-yZsma6q4vrE' \
--data '{
    "code": "vk2.a.02-Bsy..."
}'

Описание параметров

НазваниеОписание
codeКод авторизации, полученный на втором шаге
code_verifiercode_verifier из первого шага
client_idИдентификатор приложения
grant_typeТип ответа. В нашем случае будет authorization_code
redirect_uriАдрес для редиректа после авторизации. Такой же, как на первом шаге
stateПроизвольная строка. Опциональный параметр
device_idИдентификатор устройства, полученный на втором шаге
Поместите code в тело POST запроса, все остальные параметры в строку запроса.

Пример ответа

{
    "refresh_token": "vk2.a.pkzh...",
    "access_token": "vk2.a.hD-D9...",
    "id_token": "eyJ0eXAiOi...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "user_id": 1234567890,
    "state": "abracadabracodeexchange",
    "scope": "vkid.personal_info email phone"
}

Шаг 4. Обновление токенов

Если срок действия Access token истек, его следует обновить. Используйте HTTP-запрос.

Пример запроса

curl --location 'https://id.vk.ru/oauth2/auth?grant_type=refresh_token&client_id=7915193&device_id=generatedencrypteddeviceid123' \
--header 'Content-Type: application/json' \
--data '{
    "refresh_token": "vk2.a.pkzh..."
}'

Описание параметров

НазваниеОписание
grant_typeТип ответа. В нашем это refresh_token
refresh_tokenrefresh_token, полученный на третьем шаге
device_idИдентификатор устройства, полученный на втором шаге
client_idИдентификатор приложения

Пример результата запроса

{
    "refresh_token": "vk2.a.iiG...",
    "access_token": "vk2.a.02R...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "user_id": 1234567890,
    "state": "",
    "scope": "vkid.personal_info email phone"
}

Шаг 5. Инвалидация токена (выход из аккаунта)

В целях безопасности проинвалидируйте токен с помощью HTTP-запроса API, если вы хотите завершить сессию пользователя.

Пример запроса

curl --location 'https://id.vk.ru/oauth2/logout?client_id=7915193' \
--header 'Authorization: Bearer vk2.a.02R...'

Описание параметров

НазваниеОписание
access_tokenaccess_token, полученный на третьем шаге
client_idИдентификатор приложения

Пример результата запроса:

{
    "response": 1
}

Шаг 6. (Опционально) Получение пользовательских данных

Получите данные пользователя с помощью HTTP-запроса.

Пример запроса пользовательских данных

curl --location 'https://id.vk.ru/oauth2/user_info' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer vk2.a.02R...' \
--data '{
    "client_id":"7915193"
}'

Описание параметров

НазваниеОписание
access_tokenaccess_token, полученный на третьем шаге
client_idИдентификатор приложения

Пример получения пользовательских данных

{
    "user": {
        "user_id": "1234567890",
        "first_name": "Ivan",
        "last_name": "Ivanov",
        "phone": "79991234567",
        "avatar": "https://pp.userapi.com/60tZWMo4SmwcploUVl9XEt8ufnTTvDUmQ6Bj1g/mmv1pcj63C4.png",
        "email": "ivan_i123@vk.ru",
        "sex": 2,
        "verified": false,
        "birthday": "01.01.2000"
    }
}

Шаг 7. (Опционально) Получение пользовательских данных в маскированном виде

id_token позволяет получить маскированные данные пользователя.

Пример запроса маскированных данных пользователя

curl --location 'https://id.vk.ru/oauth2/public_info?client_id=51923592' \
--header 'Content-Type: application/json' \
--data '{
    "id_token": "eyJ0eXAiOi..."
}'

Описание параметров

НазваниеОписание
id_tokenid_token, полученный на третьем шаге
client_idИдентификатор приложения

Пример получения маскированных данных пользователя

{
    "user": {
        "user_id": "1234567890",
        "first_name": "Ivan",
        "last_name": "I.",
        "phone": "+42872 *** ** 29",
        "avatar": "https://pp.userapi.com/60tZWMo4SmwcploUVl9XEt8ufnTTvDUmQ6Bj1g/mmv1pcj63C4.png",
        "email": "iv***@vk.vom"
    }
}