通过Node.js的使用lambda iOS的收据验证
我正在开发在斯威夫特的iOS应用程序,并试图实施收据验证一个应用程序内购买。我无法弄清楚如何在斯威夫特实现这一点,所以不是我试过有我的应用程序通过lambda函数writtin发送请求的Node.js,看到在this问题朱利奥Roggero的例子之后。我的雨燕代码如下所示:
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let receiptString = receiptData?.base64EncodedString(options: .endLineWithLineFeed)
let invocationRequest = AWSLambdaInvokerInvocationRequest()
invocationRequest?.functionName = "sendReceiptRequest"
invocationRequest?.invocationType = AWSLambdaInvocationType.requestResponse
invocationRequest?.payload = ["receipt-data" : receiptString!, "password" : SUBSCRIPTION_SECRET]
let lambdaInvoker = AWSLambdaInvoker.default()
lock()
lambdaInvoker.invoke(invocationRequest!).continue(with: AWSExecutor.mainThread(), with: { (task:AWSTask!) -> AnyObject! in
if task.error != nil {
self.sendErrorPopup("Error: \(task.error?.localizedDescription)")
} else {
print("TOKEN: ", task.result)
}
self.unlock()
return nil
})}
我LAMBDA Node.js的功能看起来是这样,下面的例子:
function (receiptData_base64, password, production, cb)
{
var url = production ? 'buy.itunes.apple' : 'sandbox.itunes.apple'
var receiptEnvelope = {
"receipt-data": receiptData_base64,
"password":password
};
var receiptEnvelopeStr = JSON.stringify(receiptEnvelope);
var options = {
host: url,
port: 443,
path: '/verifyReceipt',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(receiptEnvelopeStr)
}
};
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
cb(true, chunk);
});
res.on('error', function (error) {
console.log("error: " + error);
cb(false, error);
});
});
req.write(receiptEnvelopeStr);
req.end();
}
然而,运行此代码时,无论是通过一个lambda测试或通过我的应用程序,我得到的只是说Response body:
{"errorMessage":"true"}
错误消息。我发现,如果我调整了代码,我可以创造更多的预期错误 - 例如,如果我有收据数据的其他值,我得到了响应21002错误代码,如果我改变“生产”为真,我得到一个错误21007。问题的部分原因是,我不知道该回调究竟应该如何work--是块里面什么我想在斯威夫特做https.request
是否正确?我得到的收据数据是否正确,因为改变它产生不同的结果格式化的印象,那么,为什么最终的结果还是错误?
编辑:
这是我先前没有注意到的是,当我运行lambda函数,行“体:(收据数据)”的出现,其中(收据数据)是底座64编码数据I发送给函数。这让我怀疑我不是在所有到达错误回调块,而且错误有事情做与我送回调的结果返回给我的应用程序的方式。这是什么块:
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
cb(true, chunk);
});
res.on('error', function (error) {
console.log("error: " + error);
cb(false, error);
});
});
应该做的?是否有可能需要启用一些权限接收回调?
回答如下:对于任何发现此之后,潜在的问题:
- 这里最大的问题是,
Content-Type
不正确。您需要发布JSON,而不是URL编码;而代码这样做,它使用了错误的类型来告诉它使用的是什么格式的服务器。它应该是application/json
不application/x-www-form-urlencoded
。 - 发送到苹果的服务器的Base64不得(截至上周,至少)包含行尾。我不知道这这里是一个问题,但它的东西,我打过去和
.endLineWithLineFeed
让我怀疑。 - 该算法用于在服务器之间进行切换。相反,允许生产和沙箱之间切换,方法应尽量核实收据到生产服务器。如果结果对象有
status
的21007
,代码应该然后尝试同样收到对沙盒服务器。一旦收据已被解码和验证,客户可以检查收据,看看哪个服务器它被反对,(在必要时)忽略沙盒收据验证。