TinkoffID
内容
预备步骤
要开始作为合作伙伴使用 Tinkoff ID,请在此页面上填写接入申请。您的申请被审核通过后,您将通过电子邮件收到 client_id
和密码。详细说明可在文档中找到。
安装
Swift Package Manager
TinkoffID
支持Swift Package Manager。您可以在此处找到为您的项目设置SPM的说明。设置项目后,只需将存储库链接添加为依赖项。
https://github.com/tinkoff-mobile-tech/TinkoffID-iOS
Cocoapods
要使用CocoaPods安装 TinkoffID
,请在你项目的 Podfile
中添加以下行:
pod 'TinkoffID'
然后在项目目录中运行 pod install
命令。
应用程序要求
为了使用SDK,需要以下条件
- iOS 10及以上
- 已注册的授权应用程序标识符(
client_id
) - 已注册的将被授权的应用程序URL方案,该方案将在授权后用于返回应用程序
- 在
plist
中添加条目,允许您的应用程序切换到蒂宁科夫应用程序
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tinkoffbank</string>
</array>
SDK公共部分的结构
ITinkoffID
负责授权的对象实现了 ITinkoffID
协议。而 ITinkoffID
协议本身是由以下协议组成的组合:
ITinkoffAuthInitiator
- 授权过程开始时的初始化器ITinkoffAuthCallbackHandler
- 从应用返回 Tinkoff 应用的回调处理器ITinkoffCredentialsRefresher
- 能够通过它们的Refresh token
更新Credentials
的对象ITinkoffSignOutInitiator
- 用于撤回授权数据的初始化器
根据应用的架构,可以直接使用 ITinkoffID
或者在系统所需部分单独使用每个子协议。
TinkoffAuthError
TinkoffAuthError
类型的 enum
描述了可能的授权错误
值 | 描述 |
---|---|
failedToLaunchApp |
无法启动 Tinkoff 应用 |
cancelledByUser |
用户在进入 Tinkoff 之后取消了授权 |
unavailable |
用户不可用授权其他应用 |
failedToObtainToken |
在返回应用后无法完成授权 |
failedToRefreshCredentials |
无法更新令牌 |
在发生错误时,建议建议用户稍后再试。
获取 ITinkoffID
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
标志提供执行授权的能力。如果标志被设置,表示用户已安装了 Tinkoff 应用程序,可以通过该应用程序登录。当使用设置标志的 startTinkoffAuth
方法调用时,将引发到指定应用程序以初始化授权的跳转,如果标志是未设置的,用户将被重定向到 App Store 中的该应用程序页面。
执行授权
开始授权需要调用 ITinkoffAuthInitiator
对象的 startTinkoffAuth
方法。
tinkoffId.startTinkoffAuth { result in
do {
let payload = try result.get()
print("Access token obtained: \(payload.accessToken)"
} catch {
print(error)
}
}
调用此方法将导致用户被引导到 Tinkoff 应用程序以确认应用程序的授权。
继续授权
用户确认授权后,将返回到授权的应用程序以完成授权。使用应用程序提供的 URL 反馈调用,将回退。该阶段应用程序的任务是将接收到的 AppDelegate
URL 传递给 ITinkoffAuthCallbackHandler
对象的 handleCallbackUrl
方法。
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return tinkoffId.handleCallbackUrl(url)
}
SDK将处理URL传递的参数,完成授权,并将对象Result<TinkoffTokenPayload, TinkoffAuthError>
传递给在调用startTinkoffAuth()
时定义的块。
更新授权数据
有时,应用程序需要获取最新的TinkoffTokenPayload
对象(例如,当旧トークンの有效期限到期时)。
为此,需要调用对象ITinkoffCredentialsRefresher
的obtainTokenPayload
方法,如下所示
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
- 用于调用Tinkoff API的令牌refreshToken
- 获取新的accessToken
所需的令牌。如果用户禁止应用程序随时随地访问,则可能不存在。idToken
- JWT格式的用户标识符expirationTimeout
-accessToken
失效并需要使用refreshToken
获取新accessToken
的时间
存储 Refresh Token
在接收 TinkoffTokenPayload
且其中包含 refreshToken
字段时,建议保存该字段的值。如此,当原有的 accessToken
变得无效时,可以请求新的 accessToken
。推荐使用 Keychain Services 存储令牌。
UI
SDK 提供了两种 Tinkoff 品牌登录按钮。第一种是带有文本的标准矩形按钮,可以设置文本、圆角和字体。还可以选择三种颜色风格和大小。还可以添加额外的文本以吸引客户。第二种是没有文本的紧凑型按钮,也可以选择三种颜色风格。
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 应用程序进行调试
在需要在不使用 Tinkoff 应用程序或 iOS 模拟器上调试 Tinkoff ID
集成时,SDK 提供了 TinkoffID 的调试实现。
与主要实现的区别
- 而不是进入 Tinkoff 应用程序,过渡会转向专门的应用程序,允许选择身份验证场景
- 不会对 Tinkoff 服务器进行请求
调试应用程序设置
要允许应用程序进入调试应用程序,您需要在您的应用程序的 plist
文件中添加以下内容
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tinkoffiddebug</string>
</array>
接下来,请将应用程序 TinkoffID Debug
安装到设备或模拟器上。项目位于 此处。
ITinkoffID
接口,因此,在遵循依赖倒置原则的情况下,您可以在不修改您的应用程序代码的情况下引入它。此外,ITinkoffIDFactory
是一个抽象工厂,这意味着在遵循相同的依赖倒置原则时,您可以用它代替已编译的 ITinkoffID
对象进行实例化。
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
那样使用获取到的对象。
调试应用程序
调用调试 ITinkoffID
实现的 startTinkoffAuth
方法后,您将进入调试应用程序。进入后,您将看到以下可能的操作列表:
返回并成功完成登录
- 返回到您的应用程序并成功返回占位符令牌返回未完成登录
- 返回到您的应用程序并尝试获取令牌时出现错误取消登录
- 返回到您的应用程序并模拟用户取消登录模拟登录不可用
- 返回到您的应用程序并模拟Tinkoff ID
对用户不可用
示例应用
SDK 附带示例应用。要运行示例,请克隆仓库,在 Example 文件夹中执行 pod install
命令,打开生成的 .xcworkspace
文件并运行项目。
应用包括 AppDelegate
和 AuthViewController
。
AppDelegate
AppDelegate
创建 AuthViewController
并将其设置为应用程序窗口的根控制器。当应用程序启动时,创建 ITinkoffIDFactory
工厂,在 applicationDidFinishLaunching
方法中收集 ITinkoffID
,并将其作为参数传递给初始化 AuthViewController
。
AppDelegate.swift
中定义了 Constant
结构,其字段之一为 clientId
类型为 String
。为了测试授权,需要将其内容替换为在 Tinkoff ID 注册时获得的 client_id
。
AuthViewController
AuthViewController
分别通过对象实现 ITinkoffAuthInitiator
、ITinkoffCredentialsRefresher
和 ITinkoffSignOutInitiator
。
在当前实现中,所有这些链接都指向同一个实现 ITinkoffID
接口的 TinkoffID
对象实例。这种做法是选择来展示使用 ITinkoffID
子接口在不同系统部分的能力。SDK 用户有权根据应用程序架构自行决定是否使用统一的 ITinkoffID
接口或所需的子接口。
有关 ITinkoffID
子接口的详细信息,请参阅 SDK 公开部分结构
一节。
在 view
加载后,控制器向其添加一个按钮,用户可以通过点击此按钮通过 Tinkoff 登录,进而启动授权过程。
支持
可以在问题部分报告错误和请求新功能。联系方式邮箱 - [email protected]
开发者
- Дмитрий Оверчук -
[email protected]
- Камиль Бакаев -
[email protected]
- Вадим Жиликов -
[email protected]