从XHR请求接收OAuth2令牌

时间:2017-08-09 08:59:44

标签: javascript typescript paypal xmlhttprequest cors

我试图通过TypeScript中的XHR-Request获取OAuth2令牌,就像这边提到的那样(https://developer.paypal.com/docs/integration/direct/make-your-first-call/)。到目前为止我的代码:

        var clientID = <clientID>;
        var secret = <mySecret>;

        var oReq = new XMLHttpRequest();
        oReq.open("POST", "https://api.sandbox.paypal.com/v1/oauth2/token", true);

        oReq.setRequestHeader('grant_type', "client_credentials");
        oReq.setRequestHeader('Username', this.clientID);
        oReq.setRequestHeader('Password', this.secret);
        oReq.setRequestHeader('Content-type', "application/x-www-form-urlencoded");
        oReq.setRequestHeader('Accept', "application/json");
        oReq.setRequestHeader('Accept-Language', "en_US");         
        oReq.onreadystatechange = function () {
            if (oReq.readyState === 4) {
                if (oReq.status === 200) {
                    console.log(oReq.responseText);
                } else { 
                    console.log("Error: " + oReq.status);
                } 
            }     
        console.log("Status: " + oReq.status);
        }; 
        console.log("Status: " + oReq.status);

        oReq.send();

可悲的是,我一直得到401作为回应。我已经尝试了使用相同的clientID和secret的curl命令,这对我有用。有人能告诉我我的代码有什么问题吗?

1 个答案:

答案 0 :(得分:1)

您获得401响应的请求不是您的POST请求,而是浏览器自动执行的CORS预检OPTIONS请求。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests详细了解触发浏览器执行预检的内容,但在此特定情况下,您要添加grant_typeUsername和{{1请求请求标头以进行所需的身份验证 - 但是您的浏览器会在没有这些标头的情况下发出预检Password请求(因为预检的目的是要求服务器指示接收请求是否正常)包括那些请求标题)。

所以会发生以下情况(仅出于说明目的使用OPTIONS复制):

curl

也就是说,$ curl -X OPTIONS -i -H "Origin: http://example.com" \ 'https://api.sandbox.paypal.com/v1/oauth2/token' HTTP/1.1 401 Unauthorized Date: Wed, 09 Aug 2017 09:08:32 GMT Server: Apache paypal-debug-id: f8963606c5654 Access-Control-Allow-Origin: http://example.com Access-Control-Expose-Headers: False HTTP_X_PP_AZ_LOCATOR: sandbox.slc Paypal-Debug-Id: f8963606c5654 Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dapiplatformproxyserv%26TIME%3D282167897%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Wed, 09 Aug 2017 09:38:32 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT Content-Length: 0 Connection: close Content-Type: text/plain; charset=ISO-8859-1 端点显然需要对https://api.sandbox.paypal.com/v1/oauth2/token个请求进行身份验证。因为它确实存在,您无法直接从浏览器中运行的前端JavaScript代码向该端点发出OPTIONS个请求。

因此,您需要从后端代码发出请求。