- Предварительные этапы
- Установка
- Требования к приложению
- Структура публичной части SDK
- Получение ITinkoffID
- Авторизация
- UI
- Отладка без приложения Тинькофф
- Пример приложения
- Поддержка
- Разработчики
Для начала работы с Tinkoff ID в качестве партнера заполните заявку на подключение на данной странице. После рассмотрения вашей заявки вы получите по электронной почте client_id
и пароль. Подробная инструкция доступна в документации.
TinkoffID
поддерживает Swift Package Manager. Инструкцию по настройке SPM для вашего проекта можно найти здесь.
После настройки проекта просто добавьте ссылку на репозиторий как зависимость:
https://github.com/tinkoff-mobile-tech/TinkoffID-iOS
Для установки TinkoffID
с помощью CocoaPods необходимо добавить следующую строчку в ваш Podfile
:
pod 'TinkoffID'
Затем выполните команду pod install
в директории проекта.
Для работы SDK необходимо следующее:
- iOS 10 и выше
- Зарегистрированный идентификатор авторизуемого приложения (
client_id
) - Зарегистрированная авторизуемым приложением URL схема, которая будет использоваться для возврата в приложение после авторизации
- Добавленная запись в
plist
, позволяющая Вашему приложению переходить в приложение Тинькофф:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tinkoffbank</string>
</array>
Авторизацией занимается объект, реализующий протокол ITinkoffID
. В свою очередь, протокол ITinkoffID
является композицией следующих протоколов:
ITinkoffAuthInitiator
- инициатор начала процесса авторизацииITinkoffAuthCallbackHandler
- обработчик возврата в приложение из приложения ТинькоффITinkoffCredentialsRefresher
- объект, умеющий обновлятьCredentials
по ихRefresh token
ITinkoffSignOutInitiator
- инициатор отзыва авторизационных данных
В зависимости от архитектуры приложения можно использовать непосредственноITinkoffID
или каждый подпротокол отдельно в требуемой части системы.
TinkoffAuthError
типа enum
описывает возможные ошибки авторизации
Значение | Описание |
---|---|
failedToLaunchApp |
Не удалось запустить приложение Тинькофф |
cancelledByUser |
Авторизация отменена пользователем после перехода в Тинькофф |
unavailable |
Авторизация сторонних приложений недоступна для пользователя |
failedToObtainToken |
Не удалось завершить авторизацию после возврата из приложения |
failedToRefreshCredentials |
Не удалось обновить токены |
При получении ошибки рекомендуется предложить пользователю попробовать позже.
SDK поставляет публичную абстракцию ITinkoffIDFactory
и публичный класс TinkoffIDFactory
, реализующий её и служащий для сборки и предоставления объекта, реализующего ITinkoffID
.
// Идентификатор приложения
let clientId = "someClient"
// URL обратного вызова, необходимый для возврата в приложение
let callbackUrl = "myapp://authorized"
// Инициализация фабрики ITinkoffID
let factory = TinkoffIDFactory(clientId: clientId,
callbackUrl: callbackUrl)
// Получение ITinkoffID
let tinkoffId = factory.build()
После получения ITinkoffID
, приложение может начинать авторизацию.
ITinkoffAuthInitiator
может предоставить информацию о возможности выполнения авторизации с помощью флага isTinkoffAuthAvailable
. Поднятый флаг означает, что у пользователя установлено приложение Тинькофф, через которое можно осуществить вход. При вызове метода startTinkoffAuth
с поднятным флагом будет осуществлен переход в заданное приложение для инициализации авторизации, в случае если флаг опущен, пользователь будет перенаправлен на страницу этого приложения в App Store.
Для начала авторизации необходимо вызвать метод startTinkoffAuth
объекта ITinkoffAuthInitiator
:
tinkoffId.startTinkoffAuth { result in
do {
let payload = try result.get()
print("Access token obtained: \(payload.accessToken)"
} catch {
print(error)
}
}
Вызов этого метода приведет к перенаправлению пользователя в приложение Тинькофф для подтверждения авторизации приложения.
После подтверждения авторизации пользователем будет произведен возврат в авторизуемое приложение для завершения авторизации. Обратный переход будет осуществлен с помощью URL обратного вызова, предоставленным приложением. Задача приложения на этом этапе в том, чтобы передать полученный AppDelegate
URL в метод handleCallbackUrl
объекта ITinkoffAuthCallbackHandler
:
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return tinkoffId.handleCallbackUrl(url)
}
SDK обработает переданные в URL параметры завершит авторизацию, передав объект Result<TinkoffTokenPayload, TinkoffAuthError>
в блок, определенный при вызове startTinkoffAuth()
.
Время от времени приложению необходимо получать актуальный объект TinkoffTokenPayload
(например, когда срок жизни предыдущего истек).
Для этого необходимо вызвать метод obtainTokenPayload
объекта ITinkoffCredentialsRefresher
как показано ниже:
let credentials: TinkoffTokenPayload = ...
tinkoffId.obtainTokenPayload(using: credentials.refreshToken) { result in
do {
let newCredentials: TinkoffTokenPayload = try result.get()
} catch {
print(error)
}
}
Иногда может возникнуть ситуация когда полученные авторизационные данные более не нужны. Например, при выходе смене или отключении аккаунта пользователя в авторизованном приложении. В таком случае, приложению необходимо выполнить отзыв авторизационных данных с помощью ITinkoffSignOutInitiator
:
let credentials: TinkoffTokenPayload = ...
tinkoffId.signOut(with: credentials.accessToken, tokenTypeHint: .access, completion: { result in
do {
_ = try result.get()
print("Signed out")
} catch {
print(error)
}
})
В результате успешной авторизации приложение получает объект Credentials
, содержащий следующие свойства:
accessToken
- токен для обращения к API ТинькоффrefreshToken
- токен, необходимый для получения новогоaccessToken
. Может отсутствовать в случае если пользователь запретил авторизуемому приложению доступ в любое времяidToken
- идентификатор пользователя в формате JWTexpirationTimeout
- время, через котороеaccessToken
станет неактуальным и нужно будет получить новый с помощьюrefreshToken
При получении TinkoffTokenPayload
и наличии у него поля refreshToken
имеет смысл сохранить значение этого поля чтобы иметь возможность запросить новый accessToken
, когда прежний станет неактивным. Рекомендуемый способ хранения токена - Keychain Services
SDK поставляет два варианта фирменных кнопок входа через Тинькофф. Первый вариант - стандартная прямоугольная кнопка с текстом, с возможностью задать текст, радиус скругления и шрифт. Так же можно выбрать один из трех вариантов цветового стиля и размера. Есть возможность добавить дополнительный текст для привлечения клиентов. Второй вариант - компактная кнопка без текста, так же можно выбрать один из трех цветовых стилей.
override func viewDidLoad() {
super.viewDidLoad()
// Создание стандартной кнопки
let button = TinkoffIDButtonBuilder.build()
// Добавление обработчика нажатия
button.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
// Добавление в иерархию
view.addSubview(button)
// Отступ кнопки от краёв
let padding: CGFloat = 16
// Расположение кнопки на экране
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: padding),
button.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -padding),
button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -padding),
])
}
Обратите внимание: после получения кнопки необходимо расположить её на экране, а также добавить обработчик события нажатия.
Для верстки рекомендуется использовать AutoLayout
без указания высоты так как она задается с помощью intrinsicContentSize
.
Более подробно ознакомиться с правилами размещения кнопки Вы можете здесь.
В случаях когда необходима отладка интеграции Tinkoff ID
без приложения Тинькофф или на симуляторе iOS, SDK предоставляет реализацию TinkoffID для отладки.
Её отличия от основной реализации:
- Вместо приложения Тинькофф переход происходит в специальное приложение, позволяющее выбрать сценарий авторизации
- Не происходит запросов к серверам Тинькофф
Для того, чтобы разрешить приложению переход в приложение для отладки, необходимо в plist
файл вашего приложения добавить следующее:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tinkoffiddebug</string>
</array>
Далее необходимо установить приложение TinkoffID Debug
на устройство или симулятор. Проект приложения находится здесь.
ℹ️ Реализация SDK для отладки использует тот же интерфейс ITinkoffID
, что и стандартная реализация, поэтому при соблюдении принципа инверсии зависимостей вы можете внедрить её без изменения кода своего приложения. Также ITinkoffIDFactory
представляет собой абстрактную фабрику, что позволяет при соблюдении того же принципа внедрять и её вместо внедрения уже собранного объекта ITinkoffID
.
Теперь, когда ваше приложение настроено и приложение-отладчик установлено, можно собрать реализацию ITinkoffID
для отладки. Сделать это можно следующим образом:
// Ссылка по которой будет осуществлен возврат в приложение
let callbackUrl: String = ""
// Конфигурация для отладки
let configuration = DebugConfiguration(
canRefreshTokens: true, // Если флаг `canRefreshTokens` поднят, то обновление токенов будет завершаться без ошибки
canLogout: true // Если флаг `canLogout` поднят, выход из приложения будет завершаться без ошибки
)
// Фабрика, возвращающая реализацию ITinkoffID для отладки
let factory: ITinkoffIDFactory = DebugTinkoffIDFactory(
callbackUrl: callbackUrl,
configuration: configuration
)
// Реализация ITinkoffID для отладки
let debugTinkoffId: ITinkoffID = factory.build()
Далее вы можете использовать полученный объект, как обычный ITinkoffID
.
После вызова метода startTinkoffAuth
у реализации ITinkoffID
для отладки вы попадете в отладочное приложение. После перехода вам будет представлен список возможных действий, а именно:
Вернуться и успешно завершить вход
- возвращает обратно в ваше приложение и успешно отдает токены-заглушкиВернуться и не завершить вход
- возвращает обратно в ваше приложение и завершает вход с ошибкой получения токеновОтменить вход
- возвращает обратно в ваше приложение и симулирует отмену входа пользователемСимуляция недоступности входа
- возвращает обратно в приложение и симулирует недоступностьTinkoff ID
для пользователя
SDK поставляется с примером приложения. Для запуска примера склонируйте репозиторий, выполните команду pod install
в папке Example, откройте сгенерированный .xcworkspace
файл и запустите проект.
Приложение включает в себя AppDelegate
и AuthViewController
.
AppDelegate
создает AuthViewController
и устанавливает его в качестве корневого контроллера окна приложения. При запуске приложения создается фабрика ITinkoffIDFactory
, собирающая ITinkoffID
в методе applicationDidFinishLaunching
и передающая его в качестве параметров при инициализации AuthViewController
.
AppDelegate.swift
определена структура Constant
, одним из полей которой является clientId
типа String
. Для тестирования авторизации необходимо заменить её содержимое client_id
, полученным при регистрации в Tinkoff ID.
AuthViewController
инициируется ссылками на объекты, реализующими ITinkoffAuthInitiator
, ITinkoffCredentialsRefresher
и ITinkoffSignOutInitiator
соответственно.
В текущей реализации все эти ссылки указывают на один и тот же экземпляр объекта TinkoffID
, реализующий интерфейс ITinkoffID
. Такой подход был выбран для демонстрации возможности использования подинтерфейсов ITinkoffID
в той или иной части системы. Пользователь SDK вправе сам решать использовать ли ему единый интерфейс ITinkoffID
или необходимый подинтерфейс в зависимости от архитектуры приложения.
Подробнее с подинтерфесами ITinkoffID
можно ознакомиться в разделе Структура публичной части SDK
.
После загрузки view
контроллер добавляет на него кнопку входа через Тинькофф, по нажатию на которую будет инициирована авторизация.
Сообщать об ошибках и запрашивать новый функционал можно в разделе Issues
Почта для обращений - [email protected]
- Дмитрий Оверчук -
[email protected]
- Камиль Бакаев -
[email protected]
- Вадим Жиликов -
[email protected]