gpt4 book ai didi

objective-c - iOS7 应用内购买回执服务器验证的 Base64 编码怪异

转载 作者:太空狗 更新时间:2023-10-30 03:32:27 24 4
gpt4 key购买 nike

我发现 iOS7 收据的 base64 编码存在一些非常奇怪的问题。

目前(Xcode5/iOS7)有两种获取应用内购买收据的方法:

  1. 已弃用的返回单个收据的方法。 [SKPaymentTransaction transactionReceipt]
  2. 来自位置 appStoreReceiptURL 的所有收据的 bundle

My App 使用信用系统销售基于网站的服务,这使得服务器收据验证成为必要。该应用程序还出售可下载的扩展程序。所以是消耗品和非消耗品的混合物。非消耗品是从 Apple 下载的,因此无需验证。消耗品是用于在网站上购买服务的积分包。

当 iOS7 和 XCode5 启动时,我更新了我的应用程序,但遇到位于 appStoreReceiptURL 的新捆绑收据。使用新样式,将所有收据捆绑在一起,我的服务器从 Apple 的 verifyReceipt 沙箱中返回此错误

[status] => 21002
[exception] => java.lang.IllegalArgumentException

在看到 stackoverflow 上的帖子说其他人也遇到过同样的问题并且当时的意见是这是一个错误或尚未添加的功能后,我放弃了。但是,我一直看到使用旧的已弃用方法的问题,这迫使我重新尝试。经过大量的调试和搜索,我终于找出了一些问题所在 - 并使其正常工作,但以一种非常丑陋的方式,我没有信心接受它。

我原以为 NSData(纯字节缓冲区)编码输出不会有太大差异。这是我看到的奇怪部分。

原始弃用的单张收据可以 base64 编码为 64 个字符行,末尾有\r\n 或没有。苹果验证服务器不关心。无论哪种方式都很开心。

对于新的收据包,除非完成两件事,否则它将无法工作。首先base64编码不能有换行符。我注意到 Apple 已将其自己的 base64 编码器添加到 iOS7 中。这就是我用来获取适用于两种收据类型的编码输出的方法。

NSString *receiptDataString = [transactionReceipt base64EncodedStringWithOptions:0];

需要做的第二件事是从服务器上收到的编码收据包中搜索并替换所有空格字符。即

$receiptdata = str_replace(' ', '+', $receiptdata);

我碰巧注意到这是我的服务器收到的收据之间的差异。为什么我不知道?我正在使用 AFNetworking-1.3.2 的 JSONRequestOperationWithRequest

    NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
for (NSString *key in parameters) {
[pairs addObject:[NSString stringWithFormat:@"%@=%@", key, [parameters objectForKey:key]]];
}
postData = [[pairs componentsJoinedByString:@"&"] dataUsingEncoding:NSUTF8StringEncoding];
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://myserver.com/index.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request

Chris Prince 在他对 this question 的回复中声称它与 AFNetworking 2 一起工作

为什么这两个 NSData 收据会导致像我看到的那样的编码/解码问题?我已经尽可能详细和清楚地在这里帮助其他人,因为我看到很多人在这里对 Apple 推出的这种新收据方法感到同样的痛苦。

最佳答案

答案原来是由于

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

不转义所有特殊字符,如 :/?#[]@!$&'()*+,;= 等。Apple 提供的新收据经过 base64 编码后,包含需要转义但未被上述 iOS lib 转义编码器转义的字符。环顾四周,我在这里找到了一个效果很好的。请参阅下面的工作代码。 (服务器现在不需要解析收据代码,可以直接从 $_POST 中使用它)

// Lifted from:
// http://stackoverflow.com/questions/2159341/nsstring-method-to-percent-escape-for-url
//
- (NSString *)urlEncodeValue:(NSString *)str {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8));
return result;
}

// Encode and pair basic parameters
NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
NSString *part;
for (NSString *key in parameters) {
NSString *encodedValue = [[parameters objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
[pairs addObject:part];
[pairs addObject:[NSString stringWithFormat:@"%@=%@", key, [parameters objectForKey:key]]];
}

// Receipt encoded and paired separately
receiptDataString = [self urlEncodeValue:receiptDataString];
part = [NSString stringWithFormat: @"receipt=%@", receiptDataString];
[pairs addObject:part];

// Post data.
postData = [[pairs componentsJoinedByString:@"&"] dataUsingEncoding:NSUTF8StringEncoding];

关于objective-c - iOS7 应用内购买回执服务器验证的 Base64 编码怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20869828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com