Swiftpack.co -  tinkoff-mobile-tech/TinkoffID-iOS as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
tinkoff-mobile-tech/TinkoffID-iOS
SDK авторизации iOS приложений через Тинькофф
.package(url: "https://github.com/tinkoff-mobile-tech/TinkoffID-iOS.git", from: "1.0.0")

TinkoffID

TinkoffID - SDK для авторизации пользователей iOS приложений с помощью аккаунта Тинькофф.

Предварительные этапы

Для начала работы с Tinkoff ID в качестве партнера заполните заявку на подключение на данной странице. После рассмотрения вашей заявки вы получите по электронной почте client_id и пароль. Подробная инструкция доступна в документации.

Установка

Swift Package Manager

TinkoffID поддерживает Swift Package Manager. Инструкцию по настройке SPM для вашего проекта можно найти здесь. После настройки проекта просто добавьте ссылку на репозиторий как зависимость:

https://github.com/tinkoff-mobile-tech/TinkoffID-iOS

Cocoapods

Для установки TinkoffID с помощью CocoaPods необходимо добавить следующую строчку в ваш Podfile:

pod 'TinkoffID'

Затем выполните команду pod install в директории проекта.

Требования к приложению

Для работы SDK необходимо следующее:

  • iOS 10 и выше
  • Зарегистрированный идентификатор авторизуемого приложения (client_id)
  • Зарегистрированная авторизуемым приложением URL схема, которая будет использоваться для возврата в приложение после авторизации

Структура публичной части SDK

ITinkoffID

Авторизацией занимается объект, реализующий протокол ITinkoffID. В свою очередь, протокол ITinkoffID является композицией следующих протоколов:

  • ITinkoffAuthInitiator - инициатор начала процесса авторизации
  • ITinkoffAuthCallbackHandler - обработчик возврата в приложение из приложения Тинькофф
  • ITinkoffCredentialsRefresher - объект, умеющий обновлять Credentials по их Refresh token
  • ITinkoffSignOutInitiator - инициатор отзыва авторизационных данных

В зависимости от архитектуры приложения можно использовать непосредственноITinkoffID или каждый подпротокол отдельно в требуемой части системы.

TinkoffAuthError

TinkoffAuthError типа enum описывает возможные ошибки авторизации

Значение Описание
failedToLaunchApp Не удалось запустить приложение Тинькофф
cancelledByUser Авторизация отменена пользователем после перехода в Тинькофф
unavailable Авторизация сторонних приложений недоступна для пользователя
failedToObtainToken Не удалось завершить авторизацию после возврата из приложения
failedToRefreshCredentials Не удалось обновить токены

При получении ошибки рекомендуется предложить пользователю попробовать позже.

Получение ITinkoffID

SDK поставляет публичный класс TinkoffIDBuilder, служащий для сборки и предоставления объекта, реализующего ITinkoffID.

// Идентификатор приложения
let clientId = "someClient"
// URL обратного вызова, необходимый для возврата в приложение
let callbackUrl = "myapp://authorized"

// Инициализация фабрики
let builder = TinkoffIDBuilder(clientId: clientId,
                               callbackUrl: callbackUrl)
// Получение ITinkoffID
let tinkoffId = builder.buildSignInEngine()

После получения 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)
    }
})

Структура TinkoffTokenPayload

В результате успешной авторизации приложение получает объект Credentials, содержащий следующие свойства:

  • accessToken - токен для обращения к API Тинькофф
  • refreshToken - токен, необходимый для получения нового accessToken. Может отсутствовать в случае если пользователь запретил авторизуемому приложению доступ в любое время
  • idToken - идентификатор пользователя в формате JWT
  • expirationTimeout - время, через которое accessToken станет неактуальным и нужно будет получить новый с помощью refreshToken

Хранение Refresh Token

При получении TinkoffTokenPayload и наличии у него поля refreshToken имеет смысл сохранить значение этого поля чтобы иметь возможность запросить новый accessToken, когда прежний станет неактивным. Рекомендуемый способ хранения токена - Keychain Services

UI

SDK поставляет фирменную кнопку входа через Тинькофф. Кнопка представлена в двух стилях: .default (высотой 56 точек) и .compact (40 точек). Для получения экземпляра кнопки необходимо использовать статический метод build класса TinkoffIDButtonBuilder:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // Создание кнопки входа
    let button = TinkoffIDButtonBuilder.build(.default)
    
    // Добавление обработчика нажатия
    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.

Более подробно ознакомиться с правилами размещения кнопки Вы можете здесь.

Пример приложения

SDK поставляется с примером приложения. Для запуска примера склонируйте репозиторий, выполните команду pod install в папке Example, откройте сгенерированный .xcworkspaceфайл и запустите проект.

Приложение включает в себя AppDelegate и AuthViewController.

AppDelegate

AppDelegate создает AuthViewController и устанавливает его в качестве корневого контроллера окна приложения. При запуске приложения создается TinkoffIDBuilder, собирающий ITinkoffID в методе applicationDidFinishLaunching и передающий его в качестве параметров при инициализации AuthViewController.

⚠️ Обратите внимание! В AppDelegate.swift определена структура Constant, одним из полей которой является clientId типа String. Для тестирования авторизации необходимо заменить её содержимое client_id, полученным при регистрации в Tinkoff ID.

AuthViewController

AuthViewController инициируется ссылками на объекты, реализующими ITinkoffAuthInitiator, ITinkoffCredentialsRefresher и ITinkoffSignOutInitiator соответственно.

В текущей реализации все эти ссылки указывают на один и тот же экземпляр объекта TinkoffID, реализующий интерфейс ITinkoffID. Такой подход был выбран для демонстрации возможности использования подинтерфейсов ITinkoffID в той или иной части системы. Пользователь SDK вправе сам решать использовать ли ему единый интерфейс ITinkoffID или необходимый подинтерфейс в зависимости от архитектуры приложения.

Подробнее с подинтерфесами ITinkoffID можно ознакомиться в разделе Структура публичной части SDK.

После загрузки view контроллер добавляет на него кнопку входа через Тинькофф, по нажатию на которую будет инициирована авторизация.

Поддержка

Сообщать об ошибках и запрашивать новый функционал можно в разделе Issues Почта для обращений - tinkoff_id@tinkoff.ru

Автор

Дмитрий Оверчук, d.overchuk@tinkoff.ru

GitHub

link
Stars: 9
Last commit: 6 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

Первый пошёл 🚀
12 weeks ago

В первой версии мы реализовали весь необходимый функционал, добавили поддержку CocoaPods, SPM, написали кучу тестов и документации

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API