365id 身份验证 iOS SDK
365id 身份验证 SDK 使您能够将 365id 服务集成到您的 iOS 应用中。我们还支持 Android。
SDK 支持识别和验证身份证件,如护照、身份证和驾照,还可以读取证件上的文本内容,并在使用时与 365id 集成服务 相关字段自动映射。
注册
如果您已经是 365id 的客户,可以通过联系 365id 的支持来请求 SDK 凭据,支持邮箱:[email protected]。
否则,您可以通过 [email protected] 与我们联系,获取更多信息。
系统集成流程
这是客户后端、客户应用、SDK和365id身份验证服务之间关系的概述表示。
flowchart
subgraph HOSTAPP[Host Application]
SDK(SDK)
end
365IDCES(365id<br> Id Verification Service)
CUSTEND[Customer Backend]
HOSTAPP --1. Request Access Token--> CUSTEND
CUSTEND --2. Access Token Response--> HOSTAPP
SDK --3. Id Verification Process--> 365IDCES
365IDCES --4. Transaction Id--> SDK
CUSTEND --4. Transaction Id--> 365IDCES
HOSTAPP --4. Transaction Id----> CUSTEND
365IDCES --5. Transaction Result----> CUSTEND
CUSTEND --6. Final Decision--> HOSTAPP
应用SDK集成流程
这是在应用中集成365id身份验证SDK与客户后端的基本流程表示。带有虚线轮廓的框是过程中可配置的步骤。
flowchart LR
subgraph APP1[APP]
user[The user interaction comes<br> to a point where<br> identification is needed]
id_begin[The identification flow<br>begins in the App]
token[An access token<br> is requested from the<br> customer backend]
user --> id_begin
id_begin --> token
end
subgraph CUSTOMER_BACKEND1[CUSTOMER BACKEND]
request[The customer backend makes<br> a request for an access token]
backend_365[The customer backend retrieves<br> an access token from the<br> 365id backend]
response[The access token is<br> delivered back to the App]
request --> backend_365
backend_365 --> response
end
subgraph APP2[APP]
valid[The app receives the<br> access token]
startSDK[The app now starts the<br> SDK with the access token]
valid --> startSDK
end
subgraph SDK
front[The user is asked to take<br>a picture of the document]
back[The user is asked to take<br>a picture of the backside<br>of the document]
nfc[The user is asked to place<br>the phone on the document<br>for NFC check]
liveness[The user is asked to perform<br> a liveness check]
result[A result and a transaction id is<br> returned to the App via<br> a callback]
front --> back
back --> nfc
nfc --> liveness
liveness --> result
style nfc stroke-dasharray: 8 8
style liveness stroke-dasharray: 8 8
end
subgraph APP3[APP]
callback[The app handles the callback<br> and gets the simple result<br> and the transaction id]
contact[The app sends the transaction id<br> to the customer backend]
callback --> contact
end
subgraph CUSTOMER_BACKEND2[CUSTOMER BACKEND]
transaction_id[The customer backend gets the<br> transaction id]
backend[The customer backend talks<br> to the 365id service and gets all<br> details extracted during the<br> id verification process]
outcome[The customer backend takes<br> a decision based on the outcome<br> of the verification process]
transaction_id --> backend
backend --> outcome
end
APP1 --> CUSTOMER_BACKEND1
CUSTOMER_BACKEND1 --> APP2
APP2 --> SDK
SDK --> APP3
APP3 --> CUSTOMER_BACKEND2
要求
- Xcode 14.0+
- iOS版本14.0及以上
- 该框架是用Swift 5.3编写的
项目设置
CocoaPods
365id身份验证SDK作为CocoaPods分发,因此您需要使用CocoaPods 1.9.0或更高版本。这可能会根据对其他包装系统的需求而改变。
-
如果您项目中尚未使用CocoaPods,请先运行
sudo gem install cocoapods
,然后运行pod init
。(有关安装CocoaPods的更多信息,请点击此处。) -
请在Pod文件的顶部添加以下内容
source 'https://github.com/CocoaPods/Specs.git'
-
请在Pod文件中添加以下内容(在target部分内部)
pod 'IdVerification365id'
- 请在Podfile底部添加以下内容
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['Pods-SampleApp-objc'].include? target.name
target.build_configurations.each do |config|
config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'YES'
config.build_settings['EMBEDDED_CONTENT_CONTAINS_SWIFT'] = ''
end
end
if ['iProov'].include? target.name
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
if ['iProov'].include? target.name
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end
end
end
end
- 运行
pod update
。
添加NFC功能
365id身份验证SDK使用NFC读取技术来验证身份证件中芯片的内容。为了使此功能正常工作,需要将其作为功能添加到集成应用中。
以下是Xcode 13.4中这样做的方法
-
将您的配置文件设置为支持近距离通信标签读取。您可以在苹果开发者页面上完成此操作。
-
打开项目目标,在“签名与能力”选项卡中,通过按+按钮添加“近距离通信标签读取”功能。
- 删除NDEF权限。
❗ 注意:如果未删除NDEF权限,则在发布到AppStore时可能会出现问题。
添加目标属性
在您的应用Info.plist中添加一个NSCameraUsageDescription
条目,说明为什么您的应用需要相机访问权限(例如,“允许访问相机以扫描身份证件。”)
在您的应用Info.plist中添加一个NFCReaderUsageDescription
条目,说明为什么您的应用需要NFC访问权限(例如,“允许访问NFC以读取电子护照。”)
在您的Info.plist中添加一个NFC标签类型描述
例如:NFC标签会话的ISO7816应用程序标识符(A0000002471001和A0000002472001)
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
<string>A0000002472001</string>
</array>
示例应用
请注意,这个仓库中有一个用Swift和SwiftUI编写的示例应用,用于演示如何使用SDK,可供参考。
开始使用
为了使用 365id 身份验证 SDK,需要按照以下步骤操作。
获取令牌
在使用 365id 身份验证 SDK 之前,您需要一个访问令牌。为了获得访问令牌,您需要使用客户端 ID 和秘密调用 Rest API。如果您没有凭证,请通过邮件联系[email protected]。取得凭证后,您可以请求访问令牌。如果访问令牌已过期,您无需请求新的访问令牌,只需使用刷新令牌端点刷新即可。
URL: https://eu.customer.365id.com
/api/v1/access_token
用于使用客户端 ID 和秘密获取新的访问令牌,也称为客户外部 ID 和许可证密钥
POST
请求
Body - application/json
{
"client_id": "string",
"client_secret": "string"
}
响应
代码 | 描述 |
---|---|
200 | 成功 |
Body - application/json
{
"access_token": "string",
"token_type": "string",
"expires_in": 0,
"refresh_token": "string",
"scope": "string"
}
代码 | 描述 |
---|---|
400 | 无效请求 |
Body - application/json
{
"error": "string",
"error_description": "string"
}
/api/v1/refresh_token
用于刷新已检索的访问令牌。在这次调用时,访问令牌可以是或几乎可以过期。
POST
请求
头部
键 | 值 |
---|---|
授权 | Bearer <访问令牌> |
Body - application/json
{
"refresh_token": "string"
}
响应
代码 | 描述 |
---|---|
200 | 成功 |
Body - application/json
{
"access_token": "string",
"token_type": "string",
"expires_in": 0,
"refresh_token": "string",
"scope": "string"
}
代码 | 描述 |
---|---|
400 | 无效请求 |
Body - application/json
{
"error": "string",
"error_description": "string"
}
访问令牌在一定时间内有效,在那之后,您将不得不使用提供的刷新令牌来刷新访问令牌。
⚠️ 安全警告:在生产型应用中,建议您通过服务器到服务器的调用来获取JWT令牌。示例应用为了简单起见,直接获取它。
调用SDK
当您在应用中获取到访问令牌后,您就可以调用start(token: String, delegate: IdVerificationEventDelegate)
函数了。这个函数需要您提供访问令牌以及您自己的IdVerificationEventDelegate
协议实现。
选择文档类型
documentType
参数是start()
的可选参数,使用它您可以选择文档类型。目前,iOS SDK支持三种类型的文档:id1、id3和document。
选择文档类型并不强制用户仅扫描那种类型的文档,而是通过调整动画和其他UI元素来鼓励用户扫描该类型的文档。
以下是如何选择文档类型的示例
IdVerification.start(
token: myToken,
documentType: DocumentType.document,
delegate: myDelegate
)
要跳过的模块
skipModules
参数是start()
的可选参数,使用它可以跳过各种识别过程,也称为模块。该参数的输入类型为IdVerificationSkipModules
,它是一个类,接受一个枚举值列表作为构造函数参数。以下是如何跳过两个模块的示例
IdVerification.start(
token: myToken,
skipModules: IdVerificationSkipModules([
// Define modules to skip here:
.faceMatch,
.nfc
]),
delegate: myDelegate
)
使用事件委托
应实现协议 IdVerificationEventDelegate
并提供一个具有 start()
函数的委托对象。这样,您将获得对身份验证过程的详细反馈,并且交易最终结果将由我们的后端系统提供,使其更加安全。
示例应用中展示了如何实现和使用委托对象。
import IdVerification365id
/// Example implementation of the IdVerificationEventDelegate
private class MyEventDelegate: IdVerificationEventDelegate {
// simplified log function
private func log(_ msg: String) { Log.info("IdVerification Event: \(msg)") }
func onStarted() {
log("The SDK started successfully.")
showSDKView()
}
func onUserDismissed() {
log("The SDK view was dismissed by the user.")
}
func onClosed() {
log("The Id Verification SDK has now released all its releasable objects.")
// The SDK is now ready to be started again.
}
func onError(_ error: IdVerificationErrorBundle) {
log("An error has ocurred during the verification process.")
hideSDKView()
}
func onCompleted(_ result: IdVerificationResult) {
log("The id verification process has completed.")
hideSDKView()
}
}
使用回调
❗ 注意:回调将被弃用,并替换为 事件委托
回调函数仅接受一个参数 TransactionResult
对象。其中包含身份验证交易的交易 ID 和状态。
使用回调的函数是 start(token: String, callBack: @escaping (TransactionResult) -> Void)
。但我们建议您使用带有 IdVerificationEventDelegate
的函数,因为它为您提供更好的控制。
Swift 示例项目中的一个回调示例
/**
* Callback Example
*/
let transactionId = result.transactionId
let status = result.status
switch status {
case .OK:
// This is returned when a transaction completes successfully
// Note: This does not mean the user identity or supplied document is verified,
// only that the transaction process itself did not end prematurely.
// The assessment shows a summary
let assessment = result.assessment
print("Verification process completed successfully with status: \(assessment)")
case .Dismissed:
// This is returned if the user dismisses the SDK view prematurely.
print("User dismissed SDK")
case .ClientException:
// This is returned if the SDK encountered an internal error. Report such
// issues to 365id as bugs!
print("Client has thrown an exception")
case .ServerException:
// This is returned if there was an issue talking to 365id Services.
// Could be a connectivity issue.
print("Server has thrown an exception")
default:
// This should not occur
print("Not supported status type was returned")
}
// Prints the entire result
print("Result: \(result)")
// Stops the SDK and de-allocates the resources
IdVerification.stop()
// Disables the SDK view in example app
self.isShowingSdkView = false
// Dismisses the SDK view
DispatchQueue.main.async {
presentationMode.wrappedValue.dismiss()
}
❗ 注意:务必在回调中调用
stop()
函数以清理分配的资源。
❗ 注意:为了返回主机应用视图,您必须关闭 Sdk 视图。
启动 SDK 视图
通过调用 IdVerification.start()
启动 SDK 并获得响应后,您应切换到 sdkMainView()
。
您可以在 SampleApp 中看到如何使用 SdkMainView()
的示例。
结果验证
为了验证结果,您将需要使用与365id服务现有或新的集成。返回的数据包含所有提取的字段以及捕获的图像和文档的评估。捕获的数据将按照GDPR和我们的官方隐私政策进行处理。数据保留时间可以在我们的客户门户中进行配置,但仅限于GDPR的范围。
有关该集成的文档不包含在此README中,它只能在请求时提供,因此请与365id支持联系[email protected]获取您的副本。
❗ 注意:示例项目未显示如何使用SDK验证结果。
自定义主题
在调用Idverification.start()
之前,您可以使用函数IdVerification.setCustomTheme()
来自定义SDK的颜色和标志。此函数的大部分参数都是可选的(除了poweredByLogo
和showAppBar
),因此您可以使用适合自己的那些。下面您将看到如何使用此函数的示例
IdVerification.setCustomTheme(
IdVerificationTheme(
surface: UIColor.white,
onSurface: UIColor.purple,
background: UIColor.white,
primary: UIColor.purple,
onPrimary: UIColor.white,
secondary: UIColor.white,
secondaryContainer: UIColor.lightGray,
onSecondary: UIColor.purple,
onSecondaryContainer: UIColor.darkGray,
appBarLogo: Image("myCustomLogo"),
poweredByLogo: .STANDARD,
showAppBar: true))
日志和遥测收集
365id IdVerification SDK使用Sentry来收集日志和遥测数据。
我们收集哪些数据?
在任何阶段,我们都不会收集用户的个人信息(PII)。这包括但不限于电子邮件地址、用户名、电话号码等。
日志记录
为了记录,我们收集以下数据以帮助我们找到和修复SDK中的问题
- SDK版本
- 堆栈跟踪
遥测
我们收集以下遥测数据来寻找SDK中的性能瓶颈和慢速过程:
- 不同请求执行所需的时间。
- 用户在每个视图上花费的时间。
如果你的应用程序使用Sentry
目前Sentry不支持同时运行多个实例或者在运行时更改DSN,因此,当SDK启动时,它会检查是否已有一个Sentry实例正在运行,如果是这样的话它将不会运行Sentry。
如果你的应用程序有一个Sentry实例正在运行,日志将被发送到你的Sentry项目。如果你的应用程序没有使用Sentry,这不会成为问题。
为了避免把我们的日志发送出去,我们建议在调用IdVerification.start()
之前,让你的应用程序退出Sentry,并在触发OnClose
回调之后重新实例化Sentry。
运行 SampleApp 项目
-
请确保您已安装 Cocoapods 并从 SampleApp 目录运行
pod install
以安装所需的依赖关系。 -
打开
SampleApp.xcworkspace
。 -
将您的
client_id
和client_secret
添加到 Credentials.swift,并将您的位置名称
和位置 ID
添加到 DeviceInformation.swift。
您可以从[email protected] 获取这些凭证。 -
现在您应该能够构建和运行项目。请注意,您需要在物理设备上运行 365id SDK;它不能在模拟器上工作。
⚠️ 安全注意事项: Sample App 使用 SDK 凭据直接从 365id 后端获取访问令牌。这是固有的不安全。这只是为了演示目的。
我们强烈建议在生产环境中通过服务器到服务器的调用来执行此步骤。
生产实现
要将 SDK 内置于您的应用中,我们建议按照以下图示实现
sequenceDiagram
participant Customer Backend
participant App
participant SDK
participant 365id Backend
App->>Customer Backend: Request Access Token
activate Customer Backend
Customer Backend->>365id Backend: Request Token using client id and secret
activate 365id Backend
365id Backend->>Customer Backend: Access Token + Refresh Token
deactivate 365id Backend
Customer Backend->>App: Access Token
deactivate Customer Backend
App->>SDK: Access Token + Location Data
activate SDK
loop Process Transaction
365id Backend->>SDK: Provide instructions for user
SDK->>365id Backend: Perform requested steps
end
SDK->>App: Transaction Id and status (Ok or Unsuccessful)
deactivate SDK
App->>Customer Backend: Transaction Id
activate Customer Backend
Customer Backend->>365id Backend: Request: Transaction details using Transaction Id
activate 365id Backend
365id Backend->>Customer Backend: Response: Transaction details
deactivate 365id Backend
Customer Backend->>App: Decide if user should be considered verified
deactivate Customer Backend
Note over Customer Backend, App: The Token needs to be refreshed for each transaction
App->>Customer Backend: Request Token
activate Customer Backend
Customer Backend->>365id Backend: Refresh Token
activate 365id Backend
365id Backend->>Customer Backend: New Access Token + New Refresh Token
deactivate 365id Backend
Customer Backend->>App: New Access Token
deactivate Customer Backend
Note over App, SDK: Now the transaction is performed as usual (see above)
在写作中,可以这样描述
- 应用请求访问令牌。这可以由应用直接处理,或者如图所示通过您的后端服务处理。请求第一个访问令牌需要客户端 ID 和客户端密钥,也称为客户外部 ID 和许可证密钥。我们的建议是将此存储在您的后端,并在首次请求访问令牌时使用它。可以使用现有访问令牌和刷新令牌请求特定设备的后续访问令牌。
- 应用使用接收到的访问令牌启动 SDK,开始交易。SDK 将接管应用,直到所有请求的步骤都完成,然后返回交易结果的摘要以及交易 ID。
- 使用交易 ID 来轮询 365id 服务有关交易详情。这里建议您的后端从应用接收此 ID,然后根据从 365id 后端 API 收到的结果做出决定。
API
完整的API文档可在这里找到: https://365id-ab.github.io/idverification-ios/documentation/idverification365id/
帮助 & 支持
如需进一步的帮助,请联系 [email protected].