面试题答案
一键面试客户端措施
- 购买请求验证:
- 在发起购买请求前,对商品信息进行本地校验,确保商品ID等信息与预期一致。可以将合法的商品ID列表存储在本地,购买时对比。
- 例如,将合法商品ID数组存储在
NSUserDefaults
或本地配置文件中,购买前:
NSArray *validProductIDs = [[NSUserDefaults standardUserDefaults] objectForKey:@"ValidProductIDs"]; if (![validProductIDs containsObject:productID]) { // 非法商品ID,处理异常 return; }
- 交易处理安全:
- 确保所有交易状态变化都在
SKPaymentTransactionObserver
的回调方法中严格处理。对于SKPaymentTransactionStatePurchased
状态,不直接信任客户端判断,而是等待服务器确认。 - 比如:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: // 向服务器发送验证请求 [self verifyPurchaseOnServer:transaction]; break; // 其他状态处理... } } }
- 确保所有交易状态变化都在
- 代码混淆与加密:
- 使用工具对Objective - C代码进行混淆,增加破解难度。例如使用
clang
的-fobjc - arc - infer - retain - release
等优化选项。 - 对敏感信息如商品价格、描述等进行加密存储,在使用时解密。可以使用
CommonCrypto
框架进行AES等加密算法。如:
#import <CommonCrypto/CommonCrypto.h> // 加密 NSData *encryptedData = [self encryptData:originalData withKey:key]; // 解密 NSData *decryptedData = [self decryptData:encryptedData withKey:key];
- 使用工具对Objective - C代码进行混淆,增加破解难度。例如使用
服务端措施
- 苹果收据验证:
- 接收客户端发送的购买收据后,向苹果的验证服务器发送验证请求。可以使用苹果提供的验证API,根据环境选择生产环境或沙盒环境的验证URL。
- 在Objective - C中可以使用
NSURLSession
进行网络请求验证,示例:
NSString *receiptDataString = [receiptData base64EncodedStringWithOptions:0]; NSDictionary *requestDict = @{@"receipt-data": receiptDataString}; NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestDict options:0 error:nil]; NSURL *url = [NSURL URLWithString:isSandbox? sandboxVerificationURL : productionVerificationURL]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; request.HTTPBody = requestData; NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 处理验证结果 }]; [task resume];
- 订单记录与验证:
- 维护购买订单记录,包括购买时间、商品信息、用户ID等。每次验证购买收据时,与订单记录进行比对,确保购买行为的一致性。
- 例如,使用数据库(如MySQL)存储订单信息,在验证时查询数据库:
SELECT * FROM purchase_orders WHERE user_id =? AND product_id =? AND purchase_time BETWEEN? AND?;
- 防止重放攻击:
- 为每次购买生成唯一的标识符(如UUID),并在服务端记录已处理的标识符。当收到购买验证请求时,检查标识符是否已被处理。
- 在Objective - C中生成UUID:
NSString *uuidString = [[NSUUID UUID] UUIDString];
可能用到的技术和方法
- 加密算法:如AES(高级加密标准)用于客户端数据加密,保证敏感信息不被轻易获取。
- HTTPS:在客户端与服务端通信过程中使用HTTPS,防止数据在传输过程中被截取和篡改。
- 数字签名:虽然苹果收据本身带有数字签名,但在服务端与客户端之间也可考虑使用数字签名技术来验证数据的完整性和来源可靠性。例如使用RSA算法生成和验证签名。