상세 컨텐츠

본문 제목

모바일 ios, android 등등 결제할때 인증 영수증 Receipt 값 웹에서 처리 관련

스마트기기개발관련

by AlrepondTech 2020. 9. 20. 07:37

본문

반응형

 

=================================

=================================

=================================

 

 

출처ㅣ https://groups.google.com/forum/#!topic/phonegap/p0mlnt7-9dI

How to Validate Receipts using phonegaps InAppPurchase Manager?
작성자 2명의 게시물 3개
 


 

 

한국어로 메시지 번역  

Does anyone have example code of how to validate receipts using PhoneGaps plugin, InAppPurchaseManager? I am looking to use the apple server, not my own to validate the receipts as well.

 

 

 

한국어로 메시지 번역  

Hi,

 

You can validate receipts using native code also using javascript.

 

Native code:

 

http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html

 

 

Java Script:

 

function verifyRecpt(transactionReceipt){

    $.ajax({

           type: "POST",

           url: "https://buy.itunes.apple.com/verifyReceipt",

          /* url: "https://sandbox.itunes.apple.com/verifyReceipt",    This link For SANDBOX Testing*/

           async: false,

           data: JSON.stringify({ "receipt-data": transactionReceipt, password: "YOUR_PASSWORD" }),

           contentType: "application/json",

           success : function(text) {

                var obj=$.parseJSON(text);

                var receiptStatus = obj.status;

               

                if(receiptStatus == 0){

                         // HERE SUCCESS VALIDATION.

                } else {

                       // HANDLE based on VALIDATION CODE

                }

           },

           error : function(xhr, textStatus, errorThrown) {

                console.log("error : " + errorThrown);

           }

        });

}

 

 

Best Regards,

SP RAJU

On Sat, Oct 6, 2012 at 5:21 AM, Spencer Labadie <spencer...@gmail.com> wrote:

Does anyone have example code of how to validate receipts using PhoneGaps plugin, InAppPurchaseManager? I am looking to use the apple server, not my own to validate the receipts as well.


-- 
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phon...@googlegroups.com
To unsubscribe from this group, send email to
phonegap+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
 
To compile in the cloud, check out build.phonegap.com
 
 

 

한국어로 메시지 번역  

Awesome thanks! 
How would I then incorporate that into my code? 

window.plugins.inAppPurchaseManager.onPurchased = function(transactionIdentifier, productId, transactionReceipt) { 
                   console.log('purchased: ' + productId); 


               window.plugins.applicationPreferences.set(productId, true, function() { 
                                                             unlockProduct(productId); 
                                                             }); 

                   /* Give coins, enable subscriptions etc */ 
               } 

 

 

=================================

=================================

=================================

 

 

출처: http://www.scriptscoop.com/t/c05b79ec2bec/ios-xmlhttprequest-cannot-load-https-sandbox-itunes-apple-com-verifyreceip.html

 

XMLHttpRequest cannot load https://sandbox.itunes.apple.com/verifyReceipt. Origin is not allowed by Access-Control-Allow-Origin

 

Apple seems to not be liking my ajax requests. I'm trying to verify the receipt in a PhoneGap app after an in-app purchase.

// prepare JSON object for Apple
/* Retrieve the receipt data from the transaction’s transactionReceipt property (on iOS) or from the receipt file inside the application bundle (on OS X) and encode it using base64 encoding.
Create a JSON object with a single key named receipt-data and the string you created in step 1. Your JSON code should look like this:
{
    "receipt-data" : "(receipt bytes here)"
} */
var data = JSON.stringify({
    'receipt-data' : btoa(transactionReceipt)
});
if(DEBUG) console.log('Data: ' + data);

var url = 'https://' + (DEBUG ? 'sandbox' : 'buy') + '.itunes.apple.com/verifyReceipt';
if(DEBUG) console.log('URL: ' + url);

// send the POST request
/* Post the JSON object to the App Store using an HTTP POST request. The URL for the store is https://buy.itunes.apple.com/verifyReceipt. */
$.ajax(url, {
    type: 'POST',
    data: data,
    dataType: 'json',
    success: function(data) {
        console.log('Request returned successfully.');

        // parse the response
        /*
        The response received from the App Store is a JSON object with two keys, status and receipt. It should look something like this:
        {
            "status" : 0,
            "receipt" : { (receipt here) }
        }
        If the value of the status key is 0, this is a valid receipt. If the value is anything other than 0, this receipt is invalid.
        */
        if(data.status === 0)
        console.log("Receipt is valid.");
    },
    error : function(jqXHR, textStatus, errorThrown) {
        console.error('Request failed with response code ' + errorThrown);
    }

});

 

I am using jQuery and have:

$(document).bind("mobileinit", function () {
    // xss
    $.support.cors = true;
    $.mobile.allowCrossDomainPages = true;
}

Has anyone tried verifying their receipt via ajax and had this problem?

Thanks.

Related questions:
XMLHttpRequest cannot load https://s3.amazonaws.com/. Origin is not allowed by Access-Control-Allow-Origin
XMLHttpRequest cannot load Origin is not allowed by Access-Control-Allow-Origin

1 answer

By olore

Domain whitelisting in Apache Cordova is a security model that controls access to outside domains, such as http://google.com. The default security policy is to block all network access

http://docs.phonegap.com/guide_whitelist_index.md.html

2 similar answers  β 

By Christian Deckert

You have to use the SFDC HTTP proxy. For this you have to define the address https://s3.amazonaws.com as "Remote Site" -> Setup -> Sec. -> Remote Sites.

Enter the URL for the remote site. All s-controls, JavaScript OnClick commands in custom buttons, Apex, and AJAX proxy calls can access this Web address from salesforce.com.

Your new request should use the endpoint url: "https://c.[Instance].visual.force.com/services/proxy".

In the header of your request you have to add 'Authorization': 'OAuth {!GETSESSIONID()}' and your api-endpoint-url 'SalesforceProxy-Endpoint', apiUrl

By Sirko

Just insert the <script> tag directly instead of this XHR wrapper and then inserting the content to a<script> tag.

function getScript() {
    var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;

    if (is_chrome) {
        // generate script element and set its source
        var s = document.createElement('script');
        s.src = "http://api.widgets.org/widget/1.1.2/widget_api.js?autoCreate=false&log=true";
        // remove the script element after loading
        s.addEventListener( 'load', function(){ s.parentNode.removeChild(s); } );
        (document.head||document.documentElement).appendChild(s);
    }
}

Besides, I don't know, why you try to remove the script element after loading. This wont affect any of the objects/methods/variables created within that code

Android WebDriver. XMLHttpRequest cannot load 'URL'. Origin 'URL' is not allowed by Access- Control-Allow-Origin. at null:1

 

 IevgenVotes: 4Relevancy: 83%

I am running my automated tests on Nexus 10 (Adndroid 4.2) using Selenium WebDriver and Java. The error I face with is. This error doesn't occur for FireFox, Chrome, IE 10. But it always occur for WebDriver on Android. Due to it Log in to the system is unavailable. WebDriver is able to click, sendKeys and etc. So the question is. Is any workaround exists to avoid this issue? May be some settings which I should change for WebDriver? May be some one faced with something like this before.

XMLHttpRequest cannot load URL. Origin not allowed by Access-Control-Allow-Origin

 Scott NewsonVotes: 5Relevancy: 80%

 

I want to make a small website that uses xml data from another domain. (Weather data from Weather Underground. www.wunderground.com). I am using just html and javascript, and writing it all in Visual Studio Express 2012 for Web. I make and send the xml request as follows. The problem is that I get the following error in the Google Chrome (version 29.0.1547.66) developer console. Or this on Internet Explorer (version 10.0.8) console. As I understand it, CORS (http. //enable-cors.

“XMLHttpRequest cannot load Origin is not allowed by Access-Control-Allow-Origin” Error for invoking SOAP request

 ArunVotes: 0Relevancy: 77%

 

Sorry for asking this question. I know this is a common issue but i am not able to find the solution. I am trying to send a xmlhttprequest to a server(different domain) for invoking rest service, What I tried is. ad1,city,sp,pc,cn will taken by getElementbyID. output what I am getting is an alert with no data. In web browser console , it is showing as Error 1. "url(Server rest service url with input parameters) 401 (Unauthorized) "and Error 2.

XMLHttpRequest cannot load *…* Origin : * is not allowed by Access-Control-Allow-Origin - ON THE SAME SERVER

 

 DeedubVotes: 0Relevancy: 74%

Hey folks I am getting this. error. But I don't udnerstand why?one page is on a wordpress page and the other is a static but both are on the same server... or is that not correct?

Cant publish via PUBNUB. Origin is not allowed by Access-Control-Allow-Origin

 

SAHbKAVotes: 0Relevancy: 71%

Make it Using javascript API. On their site works fine, but locally cant send cross-domain request. Where is the problem? request is XMLHttpRequest cannot load Origin localhost. 3000 is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load. Origin is not allowed by Access-Control-Allow-Origin

 

 lostikaVotes: 1Relevancy: 68%

Im using this code to call json file, i checked it with jslint "Results . Valid JSON", it is correct, I used it few months, but today suddenly stopped working, the console shows this. XMLHttpRequest cannot load http. //www.weburl.com/web/calc/filethree.js. Origin http. //www.weburl.com/ is not allowed by Access-Control-Allow-Origin. Im newbie in jquery, I searched some info, tried callback= , but nothing .. .

XMLHttpRequest cannot load http://localhost: /geoserver/wfs. Origin http://localhost is not allowed by Access-Control-Allow-Origin

 

 RiccardoVotes: 2Relevancy: 65%

I have this error. in my google chrome console when i make a WFS request. I use apache tomcat 6 and geoserver which run on 8081 and 8080 port. I read that this error is related to proxy. How must to resolve my problem? I run my application on Windows 7 machine.

Solr: Origin is not allowed by Access-Control-Allow-Origin

 

 Jorge LazoVotes: 0Relevancy: 62%

I have a local Solr Server running on Jetty, and I am trying to use AJAX Solr to make queries to the server but the connection is refused. I have gone through the tutorial from AJAX Solr. https. //github.com/evolvingweb/ajax-solr/wiki with no issues with the example server. Is there any way around this by modifying solr.config?

socket.io + ssl - Origin is not allowed by Access-Control-Allow-Origin

 

 holyrainVotes: 0Relevancy: 59%

I build my project with socket.io v1.2.1 , which running well on http connections. But when I change my website into ssl connection, errors coming. "puhser.mydomain.com" is the server to provide io service, and "other.mydomain.com" running as a client of pusher. Here is the code of IO Server. And, the client connect to the server like this. Then, the error comes. I have tried many ways, but didn't help. God bless me! @jfriend00 . Thank u. The domain/port of the websites are different.

ajax request to pyramid returns Origin is not allowed by Access-Control-Allow-Origin

 

 QLandsVotes: 1Relevancy: 56%

I am working with python pyramid and basically I have defined a route like this. The view mapping metashemaxml is like this. All works well if for example I call. But if I do the same request by Ajax I get. What do I need to do to allow the ajax request in pyramid? Thanks,Carlos

Origin is not allowed by Access-Control-Allow-Origin.

 

 user2881021Votes: 0Relevancy: 53%

My website http. //www.e-sports.tv.br/ is flashing a black screen when it finished loading. I don't know how to solve this, but the Developer Console returned these errors. Can someone help me figure this out?

Socket.io + Node-static Origin is not allowed by Access-Control-Allow-Origin on node-static

 

 earbVotes: 0Relevancy: 50%

I am working with node.js. I was having the issue of "XMLHttpRequest cannot load. Origin localhost. 2013 is not allowed by Access-Control-Allow-Origin." which I removed by adding Now when I added 'node-static' I used and I am starting to have the Access-Control-Allow-Origin error again even though when I look at the response header through dev-tools in chrome is clearly says How can I resolve this issue. I just started programming in node.

Origin is not allowed by Access-Control-Allow-Origin , jquery mobile

 

 Johny JazVotes: 0Relevancy: 47%

I am developing a jQuery mobile webpage in my local server. I am using XAMPP so I have an Apache server. I am trying to import a Google Calendar in my page , but I get the error . I found more than a million posts about it, I couldn't understand any of them. They are all talking about a PHP file that I need to add a header etc. I don't have any PHP files, it is all HTML and JavaScript. I also read, that I could configure Apache so that it allowed me to make cross domain connections.

Web app - “origin is not allowed by access-control-allow-origin”

 

 ryystVotes: 0Relevancy: 44%

I wrote a little javascript web app for iOS where I use XMLHTTPRequest to retrieve data from a web service (over which I have no control). JSONP is not available. I'm not using jQuery.When I access the site via file. //, it works just fine, but when I access the site via http. // on a locally hosted server, it doesn't work. Safari complains that I have already tried adding Access-Control-Allow-Origin. * to my headers, but it doesn't work. What am I doing wrong?

Origin is not allowed by Access-Control-Allow-Origin in angularjs and asp.net mvc

 

 ton.yeungVotes: 1Relevancy: 41%

I have my app.js setup like this already. is there a way to find out if this is an error on angular or asp.net mvc, because I have a cors configuration on that end too, but i don't think the browser is actually getting a chance to hit the server?

using ng-views in PhoneGap getting Origin is not allowed by Access-Control-Allow-Origin

 

 BennVotes: 0Relevancy: 38%

I am trying to get ng-views to work in android phoneapp app. I get the followingerror when I trying to navigate to one of the views via hyperlink. "Origin is not allowed by Access-Control-Allow-Origin" I have tried modifying the the cordova,xml in the res folder with no luck. From To Any advice is appreciated, below is the code. Thanks. HTML. APP.JS.

Origin is not allowed by Access-Control-Allow-Origin after meteor deployment

 

 You Hock TanVotes: 0Relevancy: 35%

I've managed to deploy my meteor project to my domain. However, I kept getting this error. Is there any way to allow domain by Access-Control-Allow-Origin in meteorjs? Thanks

Uploadifive and Amazon s3 - Origin is not allowed by Access-Control-Allow-Origin

 

Erik HonnVotes: 0Relevancy: 32%

I am trying to get Uploadifive (the HTML5 version of Uploadify) to work with Amazon S3. We already have Uploadify working, but a lost of our visitors use Safari without flash so we need Uploadifive as well. I am looking to make a POST but the problem is that the pre-flight OPTIONS request that Uploadifive sends gets a "403 Origin is not allowed by Access-Control-Allow-Origin".

Origin is not allowed by Access-Control-Allow-Origin - how to enable CORS using a very simple web stack and guice

 

 AnthonyJClinkVotes: 3Relevancy: 29%

I am not sure if the issue is the technologies involved, or my understanding of the technologies. I have an html5 application written in javascript and html hosted on an apache 2.2 server. I have a java application written in java using jetty, guice, jackson, jersey that hosts a simple REST service.

 

 

=================================

=================================

=================================

 

 

출처: http://en.efreedom.net/Question/1-13204453/XMLHttpRequest-Load-Https-Sandboxitunesapplecom-VerifyReceipt-Origin-Allowed-Access-Control-Allow-Origin

IOS-XMLHttpRequest는 https://sandbox.itunes.apple.com/verifyReceipt을 로드할 수 없습니다. 기원은 액세스 제어-허용-원본으로 허용 되지 않습니다.

애플 내 ajax 요청을 좋아하지 않는 것 같다. 한에서-애플 리 케이 션 구매 후 PhoneGap 애플 리 케이 션에서 영수증을 확인 하 려 합니다.

// prepare JSON object for Apple
/* Retrieve the receipt data from the transaction’s transactionReceipt property (on iOS) or from the receipt file inside the application bundle (on OS X) and encode it using base64 encoding.
Create a JSON object with a single key named receipt-data and the string you created in step 1. Your JSON code should look like this:
{
    "receipt-data" : "(receipt bytes here)"
} */
var data = JSON.stringify({
    'receipt-data' : btoa(transactionReceipt)
});
if(DEBUG) console.log('Data: ' + data);

var url = 'https://' + (DEBUG ? 'sandbox' : 'buy') + '.itunes.apple.com/verifyReceipt';
if(DEBUG) console.log('URL: ' + url);

// send the POST request
/* Post the JSON object to the App Store using an HTTP POST request. The URL for the store is https://buy.itunes.apple.com/verifyReceipt. */
$.ajax(url, {
    type: 'POST',
    data: data,
    dataType: 'json',
    success: function(data) {
        console.log('Request returned successfully.');

        // parse the response
        /*
        The response received from the App Store is a JSON object with two keys, status and receipt. It should look something like this:
        {
            "status" : 0,
            "receipt" : { (receipt here) }
        }
        If the value of the status key is 0, this is a valid receipt. If the value is anything other than 0, this receipt is invalid.
        */
        if(data.status === 0)
        console.log("Receipt is valid.");
    },
    error : function(jqXHR, textStatus, errorThrown) {
        console.error('Request failed with response code ' + errorThrown);
    }

});

 

내가 jQuery를 사용 하 고 있다:

$(document).bind("mobileinit", function () {
    // xss
    $.support.cors = true;
    $.mobile.allowCrossDomainPages = true;
}

사람이 시도 ajax 통해 그들의 영수증을 확인 하 고이 문제를 했다?

감사.

- See more at: http://en.efreedom.net/Question/1-13204453/XMLHttpRequest-Load-Https-Sandboxitunesapplecom-VerifyReceipt-Origin-Allowed-Access-Control-Allow-Origin#sthash.lNlijCa3.dpuf

 

 

아파치 코르도바 허용 된 도메인은 액세스를 제어 하는 보안 모델 http://google.com같은 외부 도메인에. 모든 네트워크 액세스를 차단 하는 기본 보안 정책

http://docs.phonegap.com/guide_whitelist_index.md.html

- See more at: http://en.efreedom.net/Question/1-13204453/XMLHttpRequest-Load-Https-Sandboxitunesapplecom-VerifyReceipt-Origin-Allowed-Access-Control-Allow-Origin#sthash.lNlijCa3.dpuf

 

 

=================================

=================================

=================================

 

 

출처: http://stackoverflow.com/questions/13204453/xmlhttprequest-cannot-load-https-sandbox-itunes-apple-com-verifyreceipt-origi

XMLHttpRequest cannot load https://sandbox.itunes.apple.com/verifyReceipt. Origin is not allowed by Access-Control-Allow-Origin

 

 

Apple seems to not be liking my ajax requests. I'm trying to verify the receipt in a PhoneGap app after an in-app purchase.

// prepare JSON object for Apple
/* Retrieve the receipt data from the transaction’s transactionReceipt property (on iOS) or from the receipt file inside the application bundle (on OS X) and encode it using base64 encoding.
Create a JSON object with a single key named receipt-data and the string you created in step 1. Your JSON code should look like this:
{
    "receipt-data" : "(receipt bytes here)"
} */
var data = JSON.stringify({
    'receipt-data' : btoa(transactionReceipt)
});
if(DEBUG) console.log('Data: ' + data);

var url = 'https://' + (DEBUG ? 'sandbox' : 'buy') + '.itunes.apple.com/verifyReceipt';
if(DEBUG) console.log('URL: ' + url);

// send the POST request
/* Post the JSON object to the App Store using an HTTP POST request. The URL for the store is https://buy.itunes.apple.com/verifyReceipt. */
$.ajax(url, {
    type: 'POST',
    data: data,
    dataType: 'json',
    success: function(data) {
        console.log('Request returned successfully.');

        // parse the response
        /*
        The response received from the App Store is a JSON object with two keys, status and receipt. It should look something like this:
        {
            "status" : 0,
            "receipt" : { (receipt here) }
        }
        If the value of the status key is 0, this is a valid receipt. If the value is anything other than 0, this receipt is invalid.
        */
        if(data.status === 0)
        console.log("Receipt is valid.");
    },
    error : function(jqXHR, textStatus, errorThrown) {
        console.error('Request failed with response code ' + errorThrown);
    }

});

 

I am using jQuery and have:

$(document).bind("mobileinit", function () {
    // xss
    $.support.cors = true;
    $.mobile.allowCrossDomainPages = true;
}

Has anyone tried verifying their receipt via ajax and had this problem?

Thanks.

 

 

=================================

=================================

=================================

 

 

출처: http://comments.gmane.org/gmane.comp.handhelds.phonegap/38338

 

How to Validate Receipts using phonegaps InAppPurchase Manager?

Does anyone have example code of how to validate receipts using PhoneGaps plugin, InAppPurchaseManager? I am looking to use the apple server, not my own to validate the receipts as well.
-- 
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phonegap-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
phonegap+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
 
To compile in the cloud, check out build.phonegap.com
 
 

Permalink | Reply | 

headers

Padma Raju | 9 Oct 08:46 2012

 

Re: How to Validate Receipts using phonegaps InAppPurchase Manager?

Hi,

 

You can validate receipts using native code also using javascript.

 

Native code:

 

http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html

 

 

Java Script:

function verifyRecpt(transactionReceipt){

    $.ajax({

           type: "POST",

           url: "https://buy.itunes.apple.com/verifyReceipt",

          /* url: "https://sandbox.itunes.apple.com/verifyReceipt",    This link For SANDBOX Testing*/

           async: false,

           data: JSON.stringify({ "receipt-data": transactionReceipt, password: "YOUR_PASSWORD" }),

           contentType: "application/json",

           success : function(text) {

                var obj=$.parseJSON(text);

                var receiptStatus = obj.status;

               

                if(receiptStatus == 0){

                         // HERE SUCCESS VALIDATION.

                } else {

                       // HANDLE based on VALIDATION CODE

                }

           },

           error : function(xhr, textStatus, errorThrown) {

                console.log("error : " + errorThrown);

           }

        });

}

 

 

Best Regards,

SP RAJU

On Sat, Oct 6, 2012 at 5:21 AM, Spencer Labadie <spencerlabadie <at> gmail.com> wrote:

Does anyone have example code of how to validate receipts using PhoneGaps plugin, InAppPurchaseManager? I am looking to use the apple server, not my own to validate the receipts as well.
-- 
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phonegap-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
phonegap+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
 
To compile in the cloud, check out build.phonegap.com
 
 



 

-- 
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phonegap-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
phonegap+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
 
To compile in the cloud, check out build.phonegap.com
 
 

Permalink | Reply | 

headers

Spencer Labadie | 10 Oct 08:31 2012

 

Re: How to Validate Receipts using phonegaps InAppPurchase Manager?

Awesome thanks! How would I then incorporate that into my code? window.plugins.inAppPurchaseManager.onPurchased = function(transactionIdentifier, productId, transactionReceipt) { console.log('purchased: ' + productId); window.plugins.applicationPreferences.set(productId, true, function() { unlockProduct(productId); }); /* Give coins, enable subscriptions etc */ }

 

 

=================================

=================================

=================================

 

 

 

출처: http://stackoverflow.com/questions/17600110/validating-in-app-purchase-via-jquery-21002-errors

 

I'm trying to validate a purchase using jquery, and no matter what I try, I get a "receipt data malformed" error. I've got a valid receipt which looks like this:
and I'm sending it off to the server using Jquery:
and I keep getting back this "malformed request" error message. The code's valid base64, it decompresses to:
What could be causing this? The base64's valid, the "receipt-data": [receipt] seems to be correct... Can anyone help?
jquery ios cordova in-app-purchase
add a comment

3 Answers

activeoldestvotes

up vote4down voteaccepted For posterity,
When you use jQuery's post method, the string it forms from the second argument JavaScript object is not a JSON literal. Instead, it probably is doing something like this:
becomes
almost like a GET request.
However, when you use JSON.stringify(), you get a JSON literal from a JavaScript object.
In this respect, Apple's validation server is a bit non-standard, since it expects POST data to be formatted as JSON instead of the older GET-style string.


add a comment

 

up vote1down vote I have just tried to hit your request url using chrome extension app "Postman" and got successfully this :
and i guess there is no such error "malformed request". that means there should be a error in code for making request to server.


add a comment
up vote0down vote Doing it this way works correctly, for some reason:
I have no idea why you have to pass the data as a string; surely it should be the same? Every other jquery post I've ever made was by passing the data as a json object... :/ Got the working example code from http://comments.gmane.org/gmane.comp.handhelds.phonegap/38338

 

 

=================================

=================================

=================================

 

 

 

출처: http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=hit&desc=asc&no=3141

 

    http://blog.miyu.pe.kr/298 http://stackoverflow.com/questions/17600110/validating-in-app-purchase-via-jquery-21002-errors 참조하세용~;; 2014-07-31
13:16:35
 
    ios6 하고 ios7하고 보내야되는 영수증이 다릅니다.영수증 얻는 방법도 다르고요.


아마 이 부분 구글 찾앚보면 나올겁니다

 

 

=================================

=================================

=================================

 

 

 

출처: http://stackoverflow.com/questions/19600431/verifiy-ios-receipt-with-node-js

 

Verifiy iOS Receipt with Node.js

 

After struggling a few days trying to get something to work and getting no where, I was wondering if someone has gotten iOS Receipt Validation working on Node.js. I have tried the node module iap_verifier found here but I could not get it to work properly for me. the only response I received back form Apples servers is 21002, data was malformed.
One thing that has worked for me was a client side validation request to apples servers that I got directly from the tutorials provided by Apple here, with the code shown below.
I have a bunch of different code I have been using to send a wide array of things to my node server. and all of my different attempts have failed. I have even tried just funneling the "payloadData" I constructed in the client side validation example above to my server and sending that to Apples servers with the following code:
Where the function is passed the payloadData. The response received from Apple is always 21002. I'm still basically a node novice,so I can't figure out what exactly is going wrong. I think there might be some data corruption happening when I am sending the data from ObjC to my Node server, so perhaps I am not transmitting right.
If anyone can point me in the right direction, or provide some example of how they got receipt validation to work in node for them, it would be a great help. It would be great if anyone has had any experience with the iap_verifier module, and exactly what data it requires. I'll provide any code example I need to, as I have been fighting this process for a few days now.
Thanks!
javascript ios iphone node.js
 

2 Answers

activeoldestvotes

up vote2down vote For anyone using the npm library "request", here's how to avoid that bothersome 21002 error.
add a comment

 

up vote1down vote Do you have composed correctly receiptData? Accordlying with Apple specification it should have the format
Modifying your code wrapping the base64 receipt string with receipt-data object the validation should works

 

 

=================================

=================================

=================================

 

 

 

출처: http://stackoverflow.com/questions/31105803/validating-auto-renewable-subscription-receipt-and-updating-parse-using-cloud-co

 

I am developing an iOS app that uses Parse as the backend and users subscribe using Apple's auto-renewable subscription IAP. During the Subscribe and Restore Purchases functions, I pass the receipt as a parameter in a Cloud Code function and then POST that to Apple's server via Parse, as described in this SO answer.
I would like to parse the HTTPResponse and update the user object in Parse with the expires_dateproperty of the JSON receipt. I think my Cloud Code function must be off a bit, because my console shows Result: TypeError: Cannot read property 'status' of undefined, meaning that HTTPResponse.data is undefined(?). My function is below, followed by the console log.
Also, I'm not 100% clear on whether I should be using receipt, latest_receipt, or latest_receipt_info for accessing the expires_date property, so I have some extra variables in there just to test what comes out.
(Thanks for any help as Cloud Code is the only JavaScript that I've ever written.)
Console Log
Edit
console.log(JSON.stringify(httpResponse, null, 4)); gave me
javascript ios parse.com in-app-purchase cloud-code


show 2 more comments

1 Answer

activeoldestvotes

up vote0down vote Try this:
Solved the problem for me.

 

 

 

 

반응형

 

 

728x90

 

 

=================================

=================================

=================================

 

 

 

출처ㅣ http://adrenal.tistory.com/16

 

javascript ajax 크로스 도메인 요청 하기 (CORS)

 

개요

웹 개발시 자바스크립트로 외부 서버의 경로로 ajax요청을 날리면 에러가 나면서 요청이 실패한다.

 

웹 브라우저의 콘솔창에 아래와 같은 메시지를 보게 된다.

 

크롬

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ‘[요청한 도메인]' is therefore not allowed access.

 

 

파이어폭스

교차 원본 요청 차단: 동일 출처 정책으로 인해 [요청한 도메인]에 있는 원격 자원을 읽을 수 없습니다. 자원을 같은 도메인으로 이동시키거나 CORS를 활성화하여 해결할 수 있습니다.

 

 

외부로 요청이 안되는것은 자바스크립트 엔진 표준 스팩에 동일 출처 정책(same-origin policy)이라는 보안 규칙이 있기 때문이다. 

 

 

 

동일 출처 정책(Same-Origin Policy)

웹어플리케이션 보안 모델에서 중요한 개념중 하나가 동일 출처 정책(Same-Origin Policy)이다.

관련 스팩: http://www.w3.org/Security/wiki/Same_Origin_Policy

 

 

이 정책에 의해서 자바스크립트(XMLHttpRequest)로 다른 웹페이지에 접근할때는 같은 출처(same origin)의 페이지에만 접근이 가능하다. 같은 출처라는 것은 프로토콜호스트명포트가 같다는 것을 의미한다. 즉 쉽게 말하면 웹페이지의 스크립트는 그 페이지와 같은 서버에 있는 주소로만 ajax 요청을 할 수 있다는 것이다. 

 

 

 

이정책이 초기에는 웹 사이트의 보안을 위한 좋은 방법으로 생각되었으나 요즘은 여러 도메인에 걸처서 구성되는 대규모 웹 프로젝트가 늘어나고, REST API 등을 이용한 외부 호출이 많아지는 상황에서는 거추장 스러운 기술이 되기도 하고 있다.

그래서 만들어진 추가 정책이 CORS(Cross-Origon Resource Sharing) 이다. 이 정책의 특징은 서버에서 외부 요청을 허용할 경우 ajax요청이 가능해지는 방식이다. CORS에 대해서 설명하기전에 서버의 도움없이 동일 출처 정책(same-origin policy)을 회피하여 외부 서버로 요청을 날릴 수 있는 방법을 몇가지 소개 한다.

 

 

1. 웹 브라우저 실행시 외부 요청을 허용하는 옵션을 사용

아래에서 자세하게 설명하겠지만 same origin policy는 결국 클라이언트인 웹 브라우저가 요청을 해도 되는지 판단해서 결정하는 것으로 이 과정만 무시한다면 어디든 요청을 못할 이유는 없다. 크롬같은 웹 브라우저들은 실행시 커맨드라인 옵셥을 통해서 외부 도메인 요청가능 여부를 확인하는 동작을 무시하게 할 수 있다.

 

크롬의 경우: --disable-web-security 옵션을 추가하여 크롬 실행

 

 

 

 

2. 외부 요청을 가능하게 해주는 플러그인 설치

이 부분도 아래에서 설명하겠지만 서버에서 받은 요청의 응답에 특정 header(Access-Control-Allow-Origin: *)만 추가하면 웹 브라우저가 요청이 가능한 사이트로 인식해서 요청이 가능하다. 크롬의 경우 웹스토어에 요청을 가로채서 응답에 위 header를 추가해주는 플러그인이 있다. 웹스토어에서 cors로 검색하면 확장 프로그램 검색결과에서 찾을 수 있다. 

 

추천할 만한 플러그인: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?utm_source=chrome-ntp-icon

 

 

 

 

1. 2. 번 방식은 웹 브라우저 사용자가 사용하는 브라우저를 직접 셋팅하는 방식으로 개발자라면 활용해 볼 수 있겠지만 일반 사용자가 사용해야 하는 웹페이지라면 적용이 불가능하다고 보면된다.

 

 

3. JSONP방식으로 요청

웹 브라우저에서 css나 js 같은 리소스 파일들은 동일출처 정책에 영향을 받지 않고 로딩이 가능하다. 이런점을 응용해서 외부 서버서버에서 읽어온 js 파일을 json으로 바꿔주는 일종의 편법적인 방법이다. 단점은 리소스파일을 GET 메서드로 읽어오기 때문에 GET 방식의 API만 요청이 가능하다. 자세한  사용법은 이 글의 범위를 벋어나므로 생략한다.

 

 

 

 

CORS (Cross-Origin Resource Sharing)

웹 브라우저에서 외부 도메인 서버와 통신하기 위한 방식을 표준화한 스팩이다. 서버와 클라이언트가 정해진 해더를 통해 서로 요청이나 응답에 반응할지 결정하는 방식으로 교차 출처 자원 공유(cross-origin resource sharing)라는 이름으로 표준화가 되었다. 

관련 스팩: http://www.w3.org/TR/cors/#cross-origin-request-with-preflight0

 

 

교차 출처 자원 공유(cross-origin resource sharing) 방식은 요청을 받은 웹서버가 허용 할 경우에는 다른 도메인의 웹 페이지 스크립트에서도 자원을 주고 받을 수 있게 해준다.

 

 

CORS 작동 방식

 

 

 

 

 

preflight request (사전요청)

요청하려는 URL이 외부 도메인일 경우 웹 브라우저는 preflight요청을 먼저 날리게 된다.

preflight 요청은 실제로 요청하려는 경로와 같은 URL에 대해 OPTIONS 메서드로 요청을 미리 날려보고 요청을 할 수 있는 권한이 있는지 확인한다.

 

위와 같이 CORS 요청을 편법없이 하기 위해서는 클라이언트의 처리만으로는 안되고 해당 서버측에서의 추가 처리 사항이 필요하다. 

 

 

 

 

 

서버에서 CORS (Cross-Origin Resource Sharing) 요청 핸들링하기

서버로 날라온 preflight 요청을 처리하여 웹 브라우저에서 실제 요청을 날릴 수 있도록 해준다.

 

모든 외부 도메인에서 모든 요청을 허용할 경우 처리

가장 쉬운 방법으로 모든 요청을 허용하는 방식이다.

 

1. preflight 요청을 받기 위해 OPTIONS 메서드의 요청을 받아서 컨트롤 해야 한다.

2. 모든 요청의 응답에 아래 header를 추가 한다.

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
  • Access-Control-Max-Age: 3600
  • Access-Control-Allow-Headers: Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization

 

웹 브라우저의 스크립트 엔진에서 preflight 요청 응답으로 Access-Control-Allow-Origin header에 “*" 값이 있으면 모든 도메인에서의 요청을 허용하는 것으로 판단한다.  ajax 요청이 실패하면서 발생하는 메시지는 바로 preflight요청을  날린 응답 메시지에 Access-Control-Allow-Origin해더가 없어서 요청이 허용되지 않는 다는 뜻이다.

 

spring-mvc 로 개발할시 처리법: https://spring.io/guides/gs/rest-service-cors/

 

 

 

 

외부 도메인 요청을 선별적으로 허용할 경우

먼저 cros 스팩과 관련된  header의 규격을 확인해보자.

  • Request headers (클라이언트의 요청 해더)
  • Origin: 요청을 보내는 페이지의 출처(도메인)
  • Access-Control-Request-Method: 실제 요청하려는 메서드
  • Access-Control-Request-Headers: 실제 요청에 포함되어 있는  해더 이름

 

  • Response headers (서버에서의 응답 해더)
    • Access-Control-Allow-Origin: 요청을 허용하는 출처. * 이면 모든곳에 공개되어 있음을 의미한다.
    • Access-Control-Allow-Credentials: 클라이언트 요청이 쿠키를 통해서 자격 증명을 해야 하는 경우에 true. true를 응답 받은 클라이언트는 실제요청시 서버에서 정의된 규격의 인증값이 담긴 쿠키를 같이 보내야 한다.
    • Access-Control-Expose-Headers: 클라이언트 요청에 포함되어도 되는 사용자 정의 해더.
    • Access-Control-Max-Age: 클라이언트에서 preflight 의 요청 결과를 저장할 기간을 지정. 클라이언트에서 preflight 요청의 결과를 저장하고 있을 시간이다. 해당 시간동안은 preflight요청을 다시 하지 않게 된다.
    • Access-Control-Allow-Methods: 요청을 허용하는 메서드. 기본값은 GET,POST 라고 보면된다. 이 해더가 없으면 GET과 POST요청만 가능하다. 만약 이해더가 지정이 되어 있으면, 클라이언트에서는 해더 값에 해당하는 메서드일 경우에만 실제 요청을 시도하게 된다.
    • Access-Control-Allow-Headers: 요청을 허용하는 해더. 

 

위의 request header 값을 보고 response header에 해당 출처(origin)에 허용하는 요청 스팩을 알려주는 구현을 하면 된다. 이런 처리를 미리 구현해놓은 라이브러리등은 찾아볼 수 없었다. Filter나 Interceptor등을 직접 구현해야 할것으로 보인다.

 

 

 

결론

server side

위에서 언급한것 처럼 이 정책을 회피하기 위한 다양한 방법이 있으므로 서버가 이 스팩을 지원한다고 해서 다른 보안정책을 마련하지 않으면 안된다. 일반적인 웹 브라우저에서 스크립트에 의한 Ajax 요청만 적용을 받을 수 있다고 생각해야 할 것이다. 그럼에도 불구하고 불특정 다수의 외부 클라이언트에서 요청을 받을 수 있는 open API 같은 것을 개발 중이라면 클라이어트가 각종 편법들을 동원해서 서버에 접근하지 않아도 되도록 cors요청을 핸들링해줄 필요가 있다.

 

client side

ajax요청시 에러가 날때 구글링을 통해서 단편적인 처방으로 문제를 해결하려고 하는 경우를 종종 봤는데 이번 기회에 javascript의 스팩을 이해하고 개발상황에 맞는 적절한 해결 방식을 선택할 수 있기를 바란다. 외부 서버로 ajax요청이 안될 경우 아래와 같은 단계로 처리를 생각해 볼 수 있다.

 

1. 개발자가 테스트 혹은 개발단계에서 쉽계 요청하기: 웹 브라우저 실행옵션이나 플러그인을 통한 동일출저 정책 회피

2. cors구현이 안되어 있는 서버로 ajax요청을 해야하지만 서버쪽 컨트롤이 불가능할 경우: jsonp방식으로 요청

3. ajax요청을 해야하는 다른 도메인의 서버를  클라이언트와 같이 개발하거나 서버개발쪽 수정요청이 가능한 경우: 서버에서 CORS 요청이 허용되도록 구현

 

 

 

 

 

 

참고할 페이지 링크

 

 

=================================

=================================

=================================

 

 

 

출처: http://ooz.co.kr/232

 

 

CORS 크로스 도메인 이슈 (No 'Access-Control-Allow-Origin' header is present on the requested resource)

 

웹 사이트 개발 시, 주요한 이슈중의 하나를 꼽자면 크로스 도메인(Cross Domain)이 있습니다.

 

최근 대부분의 웹 브라우저는 Javascript(JQuery)를 이용하여 AJAX 등을 통해서 다른 도메인의 서버의 URL 을 호출하여 데이터를 가져오는 경우, 보안 문제를 발생시킵니다.

 

만약 우리 웹 서비스에서만 사용하기 위해 다른 서브 도메인을 가진 API 함수를 제공하는 API 서버를 구축하였는데, 다른 웹 서비스에서 이 API 서버에 접근하여 마음대로 API를 호출하여 사용한다면 문제가 되겠죠.

 

그래서 Javascript 는 동일 출처 정책(Same Origin Policy) 라는 정책을 두어 다른 도메인의 서버에 요청하는 것을 보안 문제로 간주하고 이를 차단합니다. 즉, Javascript는 자신이 속한 동일한 도메인 내에서만 서버 요청을 허용하고, 처리해주겠다는 것인데요. 이것은 www.ozit.co.kr 도메인에서 호출된 AJAX는 www.ozit.co.kr 도메인 내에 있는 URL만을 호출할 수 있다는 의미입니다. 다시말하면 www.ozit.co.kr 도메인에서 www.tistory.com 의 URL을 AJAX로 호출할 수 없다는 의미이죠.

 

이를 다른 말로는 샌드박스(Sandbox)라고도 합니다. 샌드박스는 보호된 영역 안에서만 프로그램을 동작시킬 수 있도록 하며, 외부에 의해 영향을 받지 않도록 하는 모델을 말하는데요. 이 말뜻은 단어에서 유추할 수 있듯이 어린아이들이 뛰어놀 때, 다치지 않고, 그 안에서만 놀 수 있도록 만든 '모래 놀이통'에서 왔습니다.

 

그런데, 하나의 도메인을 가진 웹 서버에서 모든 처리를 하기에는 효율성이나 성능 등 여러 문제로 각 기능별도 여러 서버를 두는 경우가 많은데요. (API 서버, WAS 서버, 파일(이미지) 서버 등등)

물리적으로 분리된 서버이고, 다른 용도로 구축된 서버이니, 당연히 각각 다른 도메인을 가진 서버들일 텐데, 서로간에 AJAX 통신을 할 수 없는 것일까요? 즉, 서로 다른 도메인간의 호출을 의미하는 크로스 도메인 문제를 해결할 수는 없는 것일까요?

(물리적으로 동일한 서버에서도 여러 도메인을 사용할 수 있는데, 이 때에도 동일하게 크로스 도메인 이슈는 발생합니다. 크로스 도메인은 물리적인 서버나 환경의 이슈가 아닌 도메인 이름 자체의 이슈입니다.)

 

참고로 아래에서 설명드릴 방식은 서버측에서 크로스 도메인을 허용하여 문제를 해결하는 방식인데, 서버의 수정 없이 클라이언트 단에서 이를 해결하는 방법 또한 있습니다. 하지만 100% 해결은 불가능합니다. jsonp, document.domain 값 설정, 크롬 브라우저의 특수 옵션 사용 등 몇몇 방법이 있으나, 범용적인 웹 서비스에서 사용이 어렵거나(사용자가 직접 세팅해야 한다거나), 그 기능이 제한적인 경우가 대부분입니다. 실제 서버에서 해결해주는 것이 표준화된 방법이고, 100% 해결 가능한 방법입니다.

 

 

아래는 크로스 도메인 문제가 발생하면 뜨는 오류 메시지입니다.

 

 

XMLHttpRequest cannot load http://www.ozit.co.kr
No 'Access-Control-Allow-Origin' header is present on the requested resource
.
Origin 'http://abc.ozit.co.kr' is therefore not allowed access.

 

 

 

 

 

 

 

 

AJAX는 자원 요청시 XMLHttpRequest 를 통해서 처리되기 때문에 위와 같은 오류가 표시되었습니다.

 

 http://abc.ozit.co.kr 도메인의 웹 서비스에서 http://www.ozit.co.kr 도메인으로 AJAX 호출을 하였으나, 접근할 수 없다는 말입니다.

XMLHttpRequest는 http://www.ozit.co.kr 을 불러올 수 없는데, 그 이유가 Access-Control-Allow-Origin 헤더가 요청된 자원(http://www.ozit.co.kr)에 존재하지 않기 때문이라는데요.

 

파이어폭스로 보는 경우, 좀 더 자세한 한글로 된 안내를 보실 수 있는데요.

"교차 원본 요청 차단: 동일 출처 정책으로 인해 http://www.ozit.co.kr 에 있는 원격 자원을 읽을 수 없습니다. 자원을 같은 도메인으로 이동시키거나 CORS를 활성화하여 해결할 수 있습니다." 라고 합니다.

 

같은 도메인을 사용한다면 당연히 문제가 해결되겠지만, 그러지 못하는 경우라면 CORS를 활성화 시키면 되겠군요.

CORS를 간단히 설명드리자면 Cross-Origin Resource Sharing 의 약자이며, 웹 페이지의 제한된 자원을 외부의 도메인에서의 요청(접근)을 허용해주는 매커니즘입니다. CORS는 브라우저와 서버간의 Cross-Origin 요청을 허용할지 안할지에 대한 여부를 안전하게 결정하도록 상호작용할 수 있는 방법을 정의합니다.

 

 

참고 : CORS (Cross-origin resource sharing)

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

 

 

 

설명이 이것저것 잡다하게 많은데요, 실제 이를  해결하는 방법은 어렵지 않습니다.

크로스 도메인 요청을 허용할 웹 서버에서 크로스 도메인 이슈를 문제 삼지 않을 도메인을 지정해주면 됩니다.

 

들어오는 모든 요청에 대해 처리해주기 위해 Filter 를 하나 만들어야 될 것 같습니다.

필터(Filter) 이름은 SimpleCORSFilter 로 하기로 하고 SimpleCORSFilter class 를 Filter interface를 구현하여, 생성하도록 합니다.

그리고 이 필터를 웹서비스의 web.xml 에 등록하여 줍니다.

 

 

- web.xml -

 

<filter>
    <filter-name>cors</filter-name>
    <filter-class>com.company.project.util.domain.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 

 

 필터 이름은 cors이며, com.company.project.util.domain 패키지 내에 SimpleCORSFilter 클래스를 구현하였습니다.

 모든 URL 패턴(/*)에 대해 필터가 적용되도록 하였습니다.

 

 

 

- SimpleCORSFilter.java -

 

package com.company.project.util.domain;

 

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

 

@Component
public class SimpleCORSFilter implements Filter {
 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;


        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        
        response.setHeader("Access-Control-Allow-Origin", "*");

     


        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

 

위의 필터는 web.xml 에 정의한 URL 패턴에 의해서 이 웹 서버로 오는 모든 요청이 이 메서드를 지나치게 됩니다. 이 메서드를 한 번 지나고 나면 결과를 내려받는 HTML 페이지 Header에 Access-Control 과 관련된 4개의 라인이 추가되게 됩니다.

 

* response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");

 - POST, GET, OPTIONS, DELETE 요청에 대해 허용하겠다는 의미입니다.

 

* response.setHeader("Access-Control-Max-Age", "3600");
 - HTTP Request 요청에 앞서 Preflight Request 라는 요청이 발생되는데, 이는 해당 서버에 요청하는 메서드가 실행 가능한지(권한이 있는지) 확인을 위한 요청입니다. Preflight Request는 OPTIONS 메서드를 통해 서버에 전달됩니다. (위의 Methods 설정에서 OPTIONS 를 허용해 주었습니다.)

 여기서 Access-Control-Max-Age 는 Preflight request를 캐시할 시간입니다. 단위는 초단위이며, 3,600초는 1시간입니다. Preflight Request를 웹브라우저에 캐시한다면 최소 1시간동안에는 서버에 재 요청하지 않을 것입니다.

 

* response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
 이는 표준화된 규약은 아니지만, 보통 AJAX 호출이라는 것을 의미하기 위해 비공식적으로 사용되는 절차입니다. JQuery 또한 AJAX 요청 시, 이 헤더(x-requested-with)를 포함하는 것을 확인하실 수 있습니다. 여기서는 이 요청이 Ajax 요청임을 알려주기 위해 Header 에 x-request-width를 설정합니다. Form을 통한 요청과 Ajax 요청을 구분하기 위해 사용된 비표준 규약지만, 많은 라이브러리에서 이를 채택하여 사용하고 있습니다. (참고로 HTML5 부터는 Form 과 Ajax 요청을 구분할 수 있는 Header가 추가되었습니다.)

 

* response.setHeader("Access-Control-Allow-Origin", "*");
 이 부분이 가장 중요한 부분입니다. * 는 모든 도메인에 대해 허용하겠다는 의미입니다. 즉 어떤 웹사이트라도 이 서버에 접근하여 AJAX 요청하여 결과를 가져갈 수 있도록 허용하겠다는 의미입니다.

 만약 보안 이슈가 있어서 특정 도메인만 허용해야 한다면 * 대신 특정 도메인만을 지정할 수 있습니다.

 

 

response.addHeader("Access-Control-Allow-Origin", "*");

 

대신 

 

response.addHeader("Access-Control-Allow-Origin", "http://www.ozit.co.kr");
response.addHeader("Access-Control-Allow-Origin", "http://abc.ozit.co.kr");
response.addHeader("Access-Control-Allow-Origin", "http://test.ozrank.co.kr");

 

 

이렇게 쓰면

 

www.ozit.co.kr, abc.ozit.co.kr, test.ozrank.co.kr 이렇게 3개의 도메인에 대해서만 크로스 도메인을 허용하겠다는 의미입니다.

 

 

 

출처/참고 :

https://gist.github.com/zhentao/5707286 

https://spring.io/guides/gs/rest-service-cors/

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

 

 

 

=================================

=================================

=================================

 

 

출처: http://devquestion.tk/32836058/ios-receipt-validation-error-21002.html

 

I'm trying to use receipt validation with my server side. Everything is ok, but sometimes I see strange: 10 times validation is OK, but on 11 i get 21002 error. I dont know what to do. Sometimes I get error 21002 when I validate receipt first time after launch app.

App side:

func validateReceipt(productID: String) {

    let receipt = NSData(contentsOfURL: NSBundle.mainBundle().appStoreReceiptURL!)!

    let receiptdata = receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))

    let request = NSMutableURLRequest(URL: NSURL(string: "my_server_url")!)

    let session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    request.HTTPBody = receiptdata.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in

        let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary

        if (error != nil) {
            print(error!.localizedDescription)
            let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("Error could not parse JSON: '\(jsonStr)'")
        }
        else {
            if let parseJSON = json {
                 if String(parseJSON["status"]! == "ok" {
                     //do something
                     print("Validate OK")
                        }else{
                            print("Validate NOK")
                    }
            }
            else {
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Receipt Error: \(jsonStr)")
            }
        }
    })

    task.resume()
}

 

server side php script:

function getReceiptData($receipt)
{
$endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';

$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $receipt);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errmsg = curl_error($ch);
curl_close($ch);
$msg = $response.' - '.$errno.' - '.$errmsg;
echo $response;
}

foreach ($_POST as $key=>$value){
$newcontent .= $key.' '.$value;
}

$new = trim($newcontent);
$new = trim($newcontent);
$new = str_replace('_','+',$new);
$new = str_replace(' =','==',$new);

if (substr_count($new,'=') == 0){
if (strpos('=',$new) === false){
    $new .= '=';
}
}

$new = '{"receipt-data":"'.$new.'"}';
$info = getReceiptData($new);

 

Everything I do based on example http://www.brianjcoleman.com/tutorial-receipt-validation-in-swift/

So, sometimes I feel that app send to serverside wrong receipt and php script cant parse it and I receive 21002 error status. Any suggestion?

phpiosin-app-purchasereceipt-validation

Answers

 answered 3 weeks ago  Saheb Roy#1

Code 21002 means that the JSON you are sending to apple which has your shared secret and your receipt data is "misformed" or not in the format apple wants it.

Here is a screenshot with the subsequent error codes and their meaning 

 

 

 

This is how i did it (Objective C and Local Validation)

 #define kAppReceipt @"LATEST_RECEIPT"
  #define kStoreKitSecret @"YOUR SHARED SECRET"
  #define kSandboxServer @"https://sandbox.itunes.apple.com/verifyReceipt"

-(void)loadProducts{
 NSError *error;

if(![[NSUserDefaults standardUserDefaults]objectForKey:kAppReceipt]){
    NSURL *recieptURL  = [[NSBundle mainBundle]appStoreReceiptURL];
    NSError *recieptError ;
    BOOL isPresent = [recieptURL checkResourceIsReachableAndReturnError:&recieptError];
    if(!isPresent){
        return;
    }

    NSData *recieptData = [NSData dataWithContentsOfURL:recieptURL];
    if(!recieptData){
        return;
    }

    payLoad = [NSMutableDictionary dictionaryWithObject:[recieptData base64EncodedStringWithOptions:0] forKey:@"receipt-data"];
}
else {
    [payLoad setObject:[[NSUserDefaults standardUserDefaults]objectForKey:kAppReceipt] forKey:@"receipt-data"];
}


[payLoad setObject:kStoreKitSecret forKey:@"password"];

NSData *requestData = [NSJSONSerialization dataWithJSONObject:payLoad options:0 error:&error];

NSMutableURLRequest *sandBoxReq = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kSandboxServer]];
[sandBoxReq setHTTPMethod:@"POST"];
[sandBoxReq setHTTPBody:requestData];


NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:sandBoxReq completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    if(!error){
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        NSString * latestReceipt = [jsonResponse objectForKey:@"latest_receipt"];

       // this is the latest receipt that you should store in NSUSER DEFAULT to then later sent this same receipt when you make this same call
        [[NSUserDefaults standardUserDefaults] setObject:latestReceipt forKey:kAppReceipt];
    }

  }] resume];
}

 

 answered 3 weeks ago  null#2

Try removing the receipt '\n' and '\r' characters and replacing '+' with'%2B' before sending it to the server.

 

 

=================================

=================================

=================================

 

 

 

출처: https://developer.appcelerator.com/question/132064/how-to-check-receipt-without-tistorekit-api

 

How to check receipt without Ti.Storekit API


Titanium SDK : 1.8.0.1?1.8.1

Platform & version : Mac OSX 10.6.8, Xcode 4.2, iOS SDK5.0, Ti.storekit 1.4


I'm using Ti.Storekit for auto renewable subscription.

All methods of Ti.Storekit work good.(requestProducts,purchase,verifyReceipt)

But I would like to know the way to verify receipt without Ti.Storekit API.

?Here's my code

Storekit.purchase(product, function (evt) {
    switch (evt.state) {
        case Storekit.FAILED:
            alert('ERROR: Buying failed!');
            break;
        case Storekit.PURCHASED:
        case Storekit.RESTORED:
            alert('Thanks!');
            markProductAsPurchased(product.identifier);
            Ti.API.info('VerifyReceiptTarget=' + evt.receipt);

            var callback = function(evt){
                if(evt.success && evt.valid){
                    Ti.API.info('ResultOfVerify=' + JSON.stringify(evt.receipt));
                }else{
                    Ti.API.info('ErrMsg=' + evt.message);
                }
            };

            var args = {
              receipt: evt.receipt,
              sandbox: true,
              callback: callback,
              sharedSecret: MY_SHARED_SECERT
            };
            Storekit.verifyReceipt(args);
            break;
    }
});

?Output on console

[INFO] VerifyReceiptTarget = {
"signature" = "AgIY8O6fGDeFOFWmId7cx2CFDeIEnB0SS68Qhl9QFO6s0hVevU4ox+Mt3Pgh7xJnqqsbtUkWTyvAuiU625JarbdHyhILC1RfKQsENb9XcPu7dWFBv1+miJX+MeR+GORHAfMOBb7Fd9mSOrWnJ53cRnqyFwcUZ4eyh6TqFc09A6biAAADVzCCA1MwggI7oAMCAQICCGUUkU3ZWAS1MA0GCSqGSIb3DQEBBQUAMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAwwqQXBwbGUgaVR1bmVzIFN0b3JlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA5MDYxNTIyMDU1NloXDTE0MDYxNDIyMDU1NlowZDEjMCEGA1UEAwwaUHVyY2hhc2VSZWNlaXB0Q2VydGlmaWNhdGUxGzAZBgNVBAsMEkFwcGxlIGlUdW5lcyBTdG9yZTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrRjF2ct4IrSdiTChaI0g8pwv/cmHs8p/RwV/rt/91XKVhNl4XIBimKjQQNfgHsDs6yju++DrKJE7uKsphMddKYfFE5rGXsAdBEjBwRIxexTevx3HLEFGAt1moKx509dhxtiIdDgJv2YaVs49B0uJvNdy6SMqNNLHsDLzDS9oZHAgMBAAGjcjBwMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUNh3o4p2C0gEYtTJrDtdDC5FYQzowDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSpg4PyGUjFPhJXCBTMzaN+mV8k9TAQBgoqhkiG92NkBgUBBAIFADANBgkqhkiG9w0BAQUFAAOCAQEAEaSbPjtmN4C/IB3QEpK32RxacCDXdVXAeVReS5FaZxc+t88pQP93BiAxvdW/3eTSMGY5FbeAYL3etqP5gm8wrFojX0ikyVRStQ+/AQ0KEjtqB07kLs9QUe8czR8UGfdM1EumV/UgvDd4NwNYxLQMg4WTQfgkQQVy8GXZwVHgbE/UC6Y7053pGXBk51NPM3woxhd3gSRLvXj+loHsStcTEqe9pBDpmG5+sk4tw+GK3GMeEN5/+e1QT9np/Kl1nj+aBw7C0xsy0bFnaAd1cSS6xdory/CUvM6gtKsmnOOdqTesbp0bs8sn6Wqs0C9dgcxRHuOMZ2tm8npLUm7argOSzQ==";
"purchase-info" = "ewoJIm9yaWdpbmFsLXB1cmNoYXNlLWRhdGUtcHN0IiA9ICIyMDEyLTAxLTIzIDE3OjQwOjAyIEFtZXJpY2EvTG9zX0FuZ2VsZXMiOwoJInB1cmNoYXNlLWRhdGUtbXMiID0gIjEzMjkwOTk4OTYzMDUiOwoJIm9yaWdpbmFsLXRyYW5zYWN0aW9uLWlkIiA9ICIxMDAwMDAwMDIyODMxNDA2IjsKCSJleHBpcmVzLWRhdGUiID0gIjEzMjkxMDAxOTYzMDUiOwoJInRyYW5zYWN0aW9uLWlkIiA9ICIxMDAwMDAwMDI2NDI1Nzc1IjsKCSJvcmlnaW5hbC1wdXJjaGFzZS1kYXRlLW1zIiA9ICIxMzI3MzY5MjAyMDAwIjsKCSJ3ZWItb3JkZXItbGluZS1pdGVtLWlkIiA9ICIxMDAwMDAwMDEyNTQwOTIyIjsKCSJidnJzIiA9ICIyLjAuMCI7CgkiZXhwaXJlcy1kYXRlLWZvcm1hdHRlZC1wc3QiID0gIjIwMTItMDItMTIgMTg6Mjk6NTYgQW1lcmljYS9Mb3NfQW5nZWxlcyI7CgkiaXRlbS1pZCIgPSAiNDk2ODAxNjcyIjsKCSJleHBpcmVzLWRhdGUtZm9ybWF0dGVkIiA9ICIyMDEyLTAyLTEzIDAyOjI5OjU2IEV0Yy9HTVQiOwoJInByb2R1Y3QtaWQiID0gImpwLmNvLnJjc2MuYW1lZnVydS50ZXN0MDEiOwoJInB1cmNoYXNlLWRhdGUiID0gIjIwMTItMDItMTMgMDI6MjQ6NTYgRXRjL0dNVCI7Cgkib3JpZ2luYWwtcHVyY2hhc2UtZGF0ZSIgPSAiMjAxMi0wMS0yNCAwMTo0MDowMiBFdGMvR01UIjsKCSJiaWQiID0gImpwLmNvLnJjc2MuYW1lZnVydSI7CgkicHVyY2hhc2UtZGF0ZS1wc3QiID0gIjIwMTItMDItMTIgMTg6MjQ6NTYgQW1lcmljYS9Mb3NfQW5nZWxlcyI7CgkicXVhbnRpdHkiID0gIjEiOwp9";
"environment" = "Sandbox";
"pod" = "100";
"signing-status" = "0";
}

[INFO] ResultOfVerify = 
{
  "original_purchase_date_ms": "1329114184967",
  "bvrs": "1.0",
  "original_purchase_date": "2012-02-13 06:23:04 Etc/GMT",
  "quantity": "1",
  "original_purchase_date_pst": "2012-02-12 22:23:04 America/Los_Angeles",
  "original_transaction_id": "1000000026463574",
  "transaction_id": "1000000026463574",
  "bid": MY_BUNDLE_ID,
  "purchase_date": "2012-02-13 06:23:04 Etc/GMT",
  "purchase_date_pst": "2012-02-12 22:23:04 America/Los_Angeles",
  "product_id": MY_PRODUCT_ID,
  "purchase_date_ms": "1329114184967",
  "item_id": "496821819"
}

 

I tried to verify using signature or purchase-info like BASE64-Encode receipt of Objective-C native app.

But all results are 21002 error code.(receipt-data property is not correct.)

I send http-post-data with formatted json like this to https://sandbox.itunes.apple.com/verifyReceipt.

{
  "receipt-data": [signature or purchase-info in evt.receipt of Storekit.purchase],
  "password": MY_SHARED_SECERT
}

How could I check receipt is valid and the status is not expired on my server without Ti.Storekit API?

I was wondering if anyone could answer my question.

Thank you.

 

1 Comment

  • I read Apple's docs.But Apple's server returned code 21002 when I requested the receipt which was saved to my server from Titanium apps.Here's my code (C#)
  •  
  • Is it same the receipt from SKPaymentTransaction with BASE64-Encoding?
  • The receipt with BASE64-Encoding of Objective-C native apps worked well.
var receipt = [evt.receipt.purchase-info];
var shared_secret = MY_SHARED_SECRET;

var wreq = (HttpWebRequest)WebRequest.Create("https://sandbox.itunes.apple.com/verifyReceipt");
var body_str = "{\"receipt-data\":\"" + receipt + "\", \"password\":\"" + shared_secret + "\"}";
var body = Encoding.UTF8.GetBytes(body_str);

wreq.Method = "POST";
wreq.ContentLength = body.Length;
wreq.ContentType = "application/json";

using (var requestStream = wreq.GetRequestStream())
    requestStream.Write(body, 0, body.Length);

using (var response = (HttpWebResponse)wreq.GetResponse())
{
    //get verify receipt data
}

 

2 Answers

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역