iOS 集成步骤

最近更新时间:2025-09-23 11:44:51

我的收藏

概述

本文档将详细阐述 EdgeOne 客户端认证 SDK 在 iOS 项目中的具体集成步骤,包括 SDK 的引入、权限配置、初始化、认证引擎启动、挑战处理以及令牌在 API 请求中的使用。

集成步骤

注意:
开始进行集成前,请确保您已阅读并理解 移动端集成概述,了解移动端的基本认证流程。

1. 将 EdgeOne SDK 添加到您的项目

将 EdgeOne 客户端认证 SDK 集成到您的 iOS 项目中是首要步骤。您可以通过 CocoaPods 引入 SDK。在您的 Podfile 中添加以下内容:
pod 'ClientAttestation', :podspec => './SDK'
然后运行以下命令:
pod install

2. 配置 Info.plist 权限

SDK 在执行认证过程时需要基本的网络访问权限。请在您的项目 Info.plist 文件中添加以下权限声明,以确保 SDK 能够正常进行网络通信:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- 如果您的应用需要访问互联网,请确保已声明此权限 -->
<key>NSInternetPermission</key>
<true/>
注意: NSAllowsArbitraryLoads 设置允许应用加载非 HTTPS 资源。在生产环境中,强烈建议您配置 ATS 例外,仅允许必要的域通过 HTTPS 访问,以增强安全性。

3. 初始化 SDK

在使用任何认证功能之前,您需要使用您的服务域和可选的日志级别初始化 EdgeOne SDK。此操作通常在您的 AppDelegate 或应用启动时执行一次。
import ClientAttestation

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// SDK初始化
let baseUrl = "www.example.com" // 设置为业务域名
let basOptions = TCBasOptions()
basOptions.baseUrl = baseUrl
basOptions.logLevel = LOG_LEVEL_DEBUG // 可选,设置日志级别
TCBas.initialize(with: basOptions)
return true
}
参数说明:
baseUrl: 您的 EdgeOne 服务域名,例如 www.example.com
logLevel: 可选参数,用于控制 SDK 的日志输出级别。可选值包括:
LOG_LEVEL_NONE: 关闭日志(默认)
LOG_LEVEL_DEBUG: 打开 debug 以上级别日志
LOG_LEVEL_INFO: 打开 info 以上级别日志
LOG_LEVEL_WARN: 打开 warning 以上级别日志
LOG_LEVEL_ERROR: 打开 error 以上级别日志

4. 启动认证引擎

SDK 初始化完成后,您需要启动客户端认证引擎,以便 SDK 能够开始获取和管理认证令牌。此操作会启动 SDK 内部必要的后台进程。
// 启动客户端认证引擎
[[ClientAttestation sharedInstance] start];
注意: 认证引擎启动后,SDK 将准备好处理认证挑战和管理认证令牌。

5. 执行客户端认证挑战

认证挑战是获取认证令牌的关键步骤。此过程涉及获取挑战 ID 并将其传递给 SDK。SDK 会根据需要显示必要的 UI(例如在 WKWebView 中显示验证码)并计算认证令牌。这是通过 SDK 提供的 attestWithParams() 方法完成的。
// attestId
// 主动发起挑战时从控制台获取
// 被动发起挑战时从http返回的header字段中的‘EO-Attest-Challenge’获取
NSString *attestId = @"your-attestId";
AttestParams *params = [[AttestParams alloc] init];
params.attestId = attestId;
params.webView = webView; // 验证码界面显示使用的WebView
params.reqTimeoutMillis = 60000; // 可选,请求超时时间
[[ClientAttestation sharedInstance] attestWithParams:params
callback:self];

// 实现 AttestCallbackDelegate 协议
#pragma mark - AttestCallbackDelegate
- (void)onSuccess:(NSString *)token {
// 返回风险票据,把票据放在http请求中的header字段‘EO-Attest-Token’
}

- (void)onError:(NSError *)error {
// 错误信息回调
}
参数说明:
attestId: 配置挑战 ID,从控制台获取或请求结果返回。
webView: 可选参数,一个 WKWebView 实例。当认证器需要用户交互(如验证码)时,必须提供此参数。如果不需要 UI 交互,WKWebView 可以是隐藏的。
reqTimeoutMillis: 可选参数,设置请求超时时间,单位:毫秒,默认 60 秒。

6. 在 API 请求中包含认证令牌

当您的 iOS 应用向受 EdgeOne 保护的后端服务发起 API 请求时,务必在请求头中包含认证令牌。您可以通过调用 SDK 提供的 getAttestationToken() 方法随时获取当前有效的认证令牌。
// 获取客户端认证票据
NSString *attestToken = [[ClientAttestation sharedInstance] getAttestationToken];

// 示例:将令牌添加到您的网络请求头中
// 假设您正在使用 URLSession 或其他网络库
if (attestToken) {
// 您的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your-backend-api.com/data"]];
[request setValue:attestToken forHTTPHeaderField:@"EO-Attest-Token"];
// 继续发送请求
}
重要提示: 确保在每个需要认证的 API 请求中都包含此令牌。SDK 会自动管理令牌的生命周期,您只需在发送请求前获取最新令牌即可。

7. 处理服务器响应和挑战

当您的后端服务(受 EdgeOne 保护)收到客户端请求时,会检查请求中是否包含有效的认证令牌。如果请求需要认证但未携带有效令牌,服务器将返回 HTTP 428 状态码,指示客户端需要进行额外认证。这是 iOS 客户端集成中需要开发者主动适配的关键环节。
您的 iOS 应用需要实现一个机制来捕获并处理这些 HTTP 428 响应。详细流程参见 重新获取认证令牌,或续期已过期认证令牌(处理 HTTP 428 挑战)
以下是一个简化的处理 HTTP 428 挑战的示例:
// 假设您的网络请求处理逻辑
- (void)sendAPIRequest:(NSMutableURLRequest *)request {
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"网络请求错误: %@", error.localizedDescription);
return;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 428) {
// 收到 428 挑战,提取挑战 ID
NSString *challengeId = httpResponse.allHeaderFields[@"EO-Attest-Challenge"];
if (challengeId) {
NSLog(@"收到 428 挑战,挑战 ID: %@", challengeId);
// 执行认证挑战
// 根据需要创建或复用 WKWebView 实例
WKWebView *webView = [[WKWebView alloc] init];
AttestParams *attestParams = [[AttestParams alloc] init];
attestParams.attestId = challengeId;
attestParams.webView = webView;
[[ClientAttestation sharedInstance] attestWithParams:attestParams callback:self];
// 注意:这里需要处理 AttestCallbackDelegate 的回调,在 onSuccess 中重新发送请求
} else {
NSLog(@"428 响应中未找到 EO-Attest-Challenge 头");
}
} else if (httpResponse.statusCode == 200) {
NSLog(@"请求成功!");
// 处理业务数据
} else {
NSLog(@"请求失败,状态码: %ld", (long)httpResponse.statusCode);
// 处理其他错误
}
}];
[task resume];
}

// 示例调用
// NSMutableURLRequest *initialRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your-backend-api.com/protected-data"]];
// [self sendAPIRequest:initialRequest];

// 在 AttestCallbackDelegate 的 onSuccess 方法中重新发送请求
#pragma mark - AttestCallbackDelegate
- (void)onSuccess:(NSString *)token {
NSLog(@"挑战成功,获取到新令牌: %@", token);
// 重新发送原始请求,带上新令牌
// 这里需要获取到之前的请求对象,并重新发送
// 例如:
// NSMutableURLRequest *retryRequest = [self.lastFailedRequest mutableCopy]; // 假设您保存了上次失败的请求
// [retryRequest setValue:token forHTTPHeaderField:@"EO-Attest-Token"];
// [self sendAPIRequest:retryRequest];
}

- (void)onError:(NSError *)error {
NSLog(@"认证挑战失败: %@", error.localizedDescription);
}

8. (可选)使用 WKWebView 进行交互式认证(和 JS 认证)

在一些客户端认证场景中,认证器可能需要用户交互(如:交互式验证码)或执行计算密集型任务(如:加密工作量证明)。此时,EdgeOne SDK 需要特定的运行环境支持。在移动端平台上,WKWebView (iOS 平台)是实现这些功能的关键组件。
当认证器需要渲染交互式验证码 (CAPTCHA) 或运行基于 JavaScript 的加密工作量证明 (Proof-of-Work) 挑战时,SDK 要求在调用 attestWithParams() 方法时提供一个 WKWebView 实例。这意味着开发者需在应用中预先分配 WKWebView 实例,并在调用认证 API 时将其作为参数传递给 SDK。

交互式认证场景

部分认证器(例如,使用嵌入式或弹出式交互设置的 TC-CAPTCHA)需要 WKWebView 实例来渲染其交互界面。该 WKWebView 实例将在应用内部显示验证码页面,因此需要预先设置以确保正确显示。
嵌入式交互认证: 验证码界面以固定区块形式显示在设备屏幕上。为确保 UI 正确显示且不影响用户体验,开发者必须预设渲染窗口的大小、层叠顺序和对齐方式。请注意,嵌入式认证 GUI 不会随屏幕视图缩放。例如,TC-CAPTCHA 嵌入式模式建议预留至少 300x230 像素空间,以获得最佳渲染效果和用户交互体验。
弹出式交互认证: 验证码界面在认证被调用时,以浮动窗口形式显示在设备屏幕上。与嵌入式认证类似,渲染窗口的大小、层叠顺序和对齐方式也需预设。弹出式认证的特点是,当屏幕视图小于特定阈值时,弹出式认证 GUI 会自动缩放以适应不同屏幕尺寸。例如,TC-CAPTCHA 弹出式模式的初始渲染块大小为 360x360 像素。

基于 JavaScript 的认证场景

某些认证器(例如,使用无感模式的 TC-CAPTCHA)需要 WKWebView 实例作为 JavaScript 运行时环境,主要用于执行加密工作量证明 (PoW) 挑战。在此场景下,WKWebView 实例仅提供 JavaScript 执行沙箱,无需可见地渲染任何 UI。因此,传入的 WKWebView 实例无需可见,SDK 也不会将其用于 UI 渲染。