【问题标题】:Receive OAuth2 Token from XHR Request从 XHR 请求接收 OAuth2 令牌
【发布时间】:2018-01-17 01:42:14
【问题描述】:

我正在尝试通过 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 和密码的 curl 命令,这对我有用。有人可以告诉我代码有什么问题吗?

【问题讨论】:

    标签: javascript typescript paypal xmlhttprequest cors


    【解决方案1】:

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

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests 详细介绍了触发浏览器进行预检的原因,但在这种特定情况下,归结为您将 grant_typeUsernamePassword 请求标头添加到为了进行所需的身份验证,但您的浏览器发出预检 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 端点显然需要身份验证,即使对于 OPTIONS 请求也是如此。因为确实如此,所以您无法直接从浏览器中运行的前端 JavaScript 代码向该端点发出 POST 请求。

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

    【讨论】:

    • 感谢您的回答!我在需要身份验证并想要测试代码的代理后面。由于这行不通,我将找到另一种方法来测试我的代码。感谢您的回答,真的为我节省了一些时间:) 编辑:代码应该在 iOS 模拟器上运行。
    猜你喜欢
    • 1970-01-01
    • 2013-04-11
    • 2019-09-13
    • 2018-08-13
    • 2012-06-08
    • 1970-01-01
    • 2013-03-05
    • 2023-01-14
    • 2016-09-06
    相关资源
    最近更新 更多