来自客户端 javascript 的错误 400 Cognito /oauth2/token 端点

Posted

技术标签:

【中文标题】来自客户端 javascript 的错误 400 Cognito /oauth2/token 端点【英文标题】:Error 400 Cognito /oauth2/token endpoint from client-side javascript 【发布时间】:2021-12-05 21:34:10 【问题描述】:

我正在使用 AWS Cognito 托管的 UI 进行注册和登录。没有定义应用客户端密码。

我正在尝试从浏览器 javascript 代码向/oauth2/token 端点进行 API 调用,以便将 autohorization_token 与 ID 令牌交换。

问题是,当我通过 Postman 拨打电话时,Insomnia 工作正常。 但是,当我通过 浏览器中的 javascript 拨打同样的电话时,它会失败并显示400 响应类型,我无法了解原因。

这是成功的失眠电话;

但是,当我通过 javascript 进行相同的调用时,它会失败。 我已经使用了 fetch 和 XMLHttpRequest 并且结果相同。

const XHR = new XMLHttpRequest();
    
let urlEncodedData = "",
    urlEncodedDataPairs = [],
    name;

urlEncodedDataPairs.push( encodeURIComponent( 'grant_type' ) + '=' + encodeURIComponent( 'authorization_code' ) );
urlEncodedDataPairs.push( encodeURIComponent( 'code' ) + '=' + encodeURIComponent( code ) );
urlEncodedDataPairs.push( encodeURIComponent( 'client_id' ) + '=' + encodeURIComponent( 'xxxxx' ) );
urlEncodedDataPairs.push( encodeURIComponent( 'redirect_url' ) + '=' + encodeURIComponent( 'https://www.xxx.me/xxx' ) );
    
XHR.addEventListener( 'load', function(event) 
   alert( 'Yeah! Data sent and response loaded.' );
 );
    
// Define what happens in case of error
XHR.addEventListener( 'error', function(event) 
    alert( 'Oops! Something went wrong.' );
);
    
// Set up our request
XHR.open( 'POST', 'https://xxx.auth.us-west-2.amazoncognito.com/oauth2/token' );
    
// Add the required HTTP header for form data POST requests
XHR.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
    
// Finally, send our data.
XHR.send( urlEncodedData );

这是我得到的回复:

我用fetch尝试了同样的请求,结果是一样的。

   let tokenRequest = new Request(tokenURL, 
            method: 'POST',
            headers: 
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
                'Origin' : 'https://www.xxx.me'
            ,
            body: new URLSearchParams(
                'grant_type': 'authorization_code',
                'code': code,
                'client_id': 'xxx',
                'redirect_url': 'https://www.xxx.me/xxx'
            ).toString()

        );

        let response = await fetch(tokenRequest);
        let data = await response.json();

当我检查浏览器开发人员工具以查看对内容类型 = application/x-www-form-urlencoded 的身份验证端点进行的其他 POST 调用时,我意识到了一件事,它显示了添加到 URL 的查询参数,如下所示,但是,对于我的电话,参数不编码为 URL 的一部分。我不确定问题是否与此有关。

知道如何使用客户端 javascript 进行此调用吗?

【问题讨论】:

我认为您可以使用 Postman 的 Fetch 或 jQuery 检查 Javascript 的确切格式 - 工作案例的代码片段并将其用作模板来重新构建您的代码。 你确定code在你的请求被发送时被定义了吗? @AndrewGillis 是的,我发送代码。 【参考方案1】:

看起来浏览器使用的是redirect_url,这是错误的,而邮递员使用的是redirect_uri,这是正确的。此外,您应该使用 PKCE 使消息更安全 - 请参阅我的blog post 的第 4 步和第 8 步以了解其外观。

另请注意,在 OAuth 中,如果提供了无法识别的客户端 ID 或重定向 URI,通常不会返回错误详细信息或返回应用程序。如果这些都正确,您应该改为在响应负载中接收标准 OAuth errorerror_description 字段。

【讨论】:

重定向 URL 相同。你是对的,回应并没有说明什么。 URL 值相同,但浏览器代码中 redirect_url 字段的名称错误 - 它应该以 i 结尾,而不是 l 伟大的收获!谢谢,我改了,结果还是一样。 实际上检查URL到URI并添加这一行解决了这个问题。 urlEncodedData = urlEncodedDataPairs.join( '&' ).replace( /%20/g, '+' );

以上是关于来自客户端 javascript 的错误 400 Cognito /oauth2/token 端点的主要内容,如果未能解决你的问题,请参考以下文章

使用来自 Angular JS 的 Web API 令牌身份验证时出现错误请求 (400)

Angular / Nest / GraphQL - 无法上传文件(400 错误请求或 500)

从 JQuery 调用 WCF 服务:跨域 OPTIONS 请求给出错误 400

雅虎财经 API 错误 400 在亚洲

来自包含双精度数字的 Json 帖子的错误 400(错误请求)

400 错误。需要收件人地址。 JavaScript