NodeJS OAuth2:不一致API始终以{"错误":"授权无效"}

disbfnqx  于 2023-03-01  发布在  Node.js
关注(0)|答案(5)|浏览(124)

我尝试在我的node.js应用程序中实现Discord OAuth2。只要我尝试从给定的授权码获取访问令牌,我总是得到HTTP响应Error 400 {" error ":"授权无效"}

let xhr = new XMLHttpRequest()
xhr.open('POST', 'https://discord.com/api/oauth2/token')

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

let payload ={
    client_id: clientID,
    client_secret: clientSecret,
    grant_type: 'authorization_code',
    code: code,
    redirect_uri: redirectUrl,
    scope: 'identify'
};

console.log(payload)
xhr.send(JSON.stringify(payload))

xhr.onreadystatechange = () => {
    console.log(xhr.status)
    console.log(xhr.responseText)
}

xhr.onerror = () => {
    console.log('Failed')
}
izkcnapc

izkcnapc1#

好的,我解决了这个问题。对于每个遇到和我一样问题的人,我通过使用axios和querystring将POST请求发送到Discord API(https://github.com/discord/discord-api-docs/issues/1131)来解决它
看来JSON和x-www-form-urlencoded格式存在问题。

hl0ma9xz

hl0ma9xz2#

有效载荷不应该是JS对象,而应该是表单数据,即

let payload = new FormData();
payload.append("key in string","value in string")
vd2z7a6w

vd2z7a6w3#

我在尝试使用 Next.js的GetServerSideProps 函数时遇到了同样的问题。
在搜索了很多之后,我在Github上找到了一个解决这个问题的封闭问题(Github问题:与OAuth2的深度链接不起作用)。基本上,我们不能在身份验证请求的主体上使用JSON对象。我们必须使用URLSearchParams对象代替。
有效负载应如下所示:

const payload = new URLSearchParams()

payload.append('client_id', process.env.DISCORD_CLIENT_ID)
payload.append('client_secret', process.env.DISCORD_CLIENT_SECRET)
payload.append('grant_type', 'authorization_code')
payload.append('redirect_uri', process.env.DISCORD_REDIRECT_URI)
payload.append('code', accessCode)
payload.append('scope', 'identify')
gpfsuwkq

gpfsuwkq4#

在我的情况下,这是一个非常愚蠢的错误,我发送的不是“response_type”,而是“response_type“(带空格);当我打印HTML格式的字符串并看到%20时,我随机意识到请😂确保参数具有正确的名称!

2izufjch

2izufjch5#

这不是Discord的API或OAuth2.0或类似的东西的问题。您在这里做错的是,您发送了一个JSON字符串作为请求的主体,同时发送了一个标头,说它实际上是URL编码格式(application/x-www-form-urlencoded),但显然不是。
发送application/x-www-form-urlencoded的请求时,请求体需要进行URL编码,而不是JSON字符串化。
一种方法是使用Node内置的querystring模块中的querystring.stringify()方法,如下所示:

import * as querystring from "node:querystring";

let xhr = new XMLHttpRequest()
xhr.open('POST', 'https://discord.com/api/oauth2/token')

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

let payload ={
    client_id: clientID,
    client_secret: clientSecret,
    grant_type: 'authorization_code',
    code: code,
    redirect_uri: redirectUrl,
    scope: 'identify'
};
let URLEncodedPayload = Object.keys(payload).map(key => );

console.log(payload)
xhr.send(querystring.stringify(details))

xhr.onreadystatechange = () => {
    console.log(xhr.status)
    console.log(xhr.responseText)
}

xhr.onerror = () => {
    console.log('Failed')
}

相关问题