通过 Node-Fetch 检索 OAuth2 令牌
Posted
技术标签:
【中文标题】通过 Node-Fetch 检索 OAuth2 令牌【英文标题】:Retrieving OAuth2 Token Via Node-Fetch 【发布时间】:2020-10-22 21:50:36 【问题描述】:问题是我正在尝试检索 OAuth2 令牌。由于request
已被弃用,我为此使用node-fetch
。虽然我可以让它与request
一起工作,但我不能与node-fetch
一起工作。
我已经阅读了很多关于这里的帖子,但似乎没有一个真正给出真正有效的一致答案。我承认我看起来还不够好。我将其包装在测试中可能也很复杂,但由于我收到的错误消息,感觉并非如此。
这是有效的代码(请注意,我必须更改详细信息以保护内部 URL):
var request = require("request");
var options =
method: "POST",
url: "https://some-url/realms/my-realm/protocol/openid-connect/token",
headers: "Content-Type": "application/x-www-form-urlencoded" ,
form:
username: "JeffUser",
password: "jeff-password",
grant_type: "password",
client_id: "jeff-client",
client_secret: "jeff-client"
;
request(options, function(error, response, body)
if (error) throw new Error(error);
console.log(body);
)
这行得通,我得到了令牌。这是我在node-fetch
(包含在测试中)中尝试的失败:
const assert = require("chai").assert;
const fetch = require("node-fetch")
describe("Test API", function()
let api_token = "";
it("gets a token", async function()
api_token = await fetch("https://some-url/realms/my-realm/protocol/openid-connect/token",
method: "post",
headers:
"Content-Type": "application/x-www-form-urlencoded",
,
form:
username: "JeffUser",
password: "jeff-password",
grant_type: "password",
client_id: "jeff-client",
client_secret: "jeff-client"
).then (response =>
return response.json();
);
console.log(token);
);
);
这里发生的是我从该测试中得到以下输出:
error: 'invalid_request',
error_description: 'Missing form parameter: grant_type'
我已尝试按照某些搜索的建议将 form
更改为 body
,但这似乎没有任何效果。我尝试用 JSON.stringify()
包装 form:
数据,正如其他一些搜索所建议的那样,但这也导致了同样的错误被报告。
【问题讨论】:
它需要是body
而不是form
。而且您可能需要自己处理正确格式的数据编码,不确定是否有任何自动为您做这件事。
github.com/node-fetch/node-fetch#post-with-form-parameters - 使用URLSearchParams
之类的东西以application/x-www-form-urlencoded
要求的正确格式提供您的数据。
@CBroe:谢谢。但是不清楚为什么request
代码有效,我不使用“body”。此外,没有其他逻辑(我知道)专门针对编码做任何事情。基本上我正在尝试将request
中的工作内容移植到node-fetch
。我会试试URLSearchParams
的事情。
就是这样! URLSearchParams
是我需要的。谢谢!
【参考方案1】:
这要感谢@CBroe,他在 cmets 中为我提供了答案。我会将解决方案放在这里,以供遇到此问题的其他人使用。这是我必须做的:
const assert = require("chai").assert;
const fetch = require("node-fetch")
const params = new URLSearchParams();
params.append("grant_type", "password");
params.append("username", "JeffUser");
params.append("password", "jeff-password");
params.append("client_id", "jeff-client");
params.append("client_secret", "jeff-client");
describe("Test API", function()
let api_token = "";
it("gets a token", async function()
api_token = await fetch("https://some-url/realms/my-realm/protocol/openid-connect/token",
method: "post",
headers:
"Content-Type": "application/x-www-form-urlencoded",
,
body: params
).then (response =>
return response.json();
);
console.log(token);
);
);
我确保使用body
而不是form
。我还使用URLSearchParams
创建了一系列参数,并将其传递给body
参数。这就是诀窍!我现在得到了授权令牌。
【讨论】:
【参考方案2】:const buffer = require("buffer")
const fetch = require("node-fetch")
let url = 'www.exampl.com/token';
let client_id = '123';
let client_secret = '323';
let username = 'test';
let password = 'test';
let basicAuth = buffer.from(`$client_id:$client_secret`).toString("base64");
const response = await fetch(url,
method:"POST",
headers:
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json; charset=UTF-8",
Authorization: `Basic $basicAuth`,
,
body:`grant_type=password&username=$username&password=$password&scope=xfds`,
);
let token = await response.json();
console.log(token)
【讨论】:
以上是关于通过 Node-Fetch 检索 OAuth2 令牌的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 node-fetch 通过 discord webhook 发送图像?
错误 redirect_uri:“不是格式正确的 URL。”在不和谐的 OAuth2 中