概述
本文档将详细阐述 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 ClientAttestationfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// SDK初始化let baseUrl = "www.example.com" // 设置为业务域名let basOptions = TCBasOptions()basOptions.baseUrl = baseUrlbasOptions.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; // 验证码界面显示使用的WebViewparams.reqTimeoutMillis = 60000; // 可选,请求超时时间[[ClientAttestation sharedInstance] attestWithParams:paramscallback: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 客户端集成中需要开发者主动适配的关键环节。
以下是一个简化的处理 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 挑战,提取挑战 IDNSString *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 渲染。