首页 > 解决方案 > 通过 Node-Fetch 检索 OAuth2 令牌

问题描述

问题是我正在尝试检索 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'
}

我已经尝试按照一些搜索的建议更改formbody,但这似乎没有任何效果。我尝试像其他搜索所建议的那样form: { }用 a 包装数据,JSON.stringify()但这也导致报告相同的错误。

标签: javascriptoauth-2.0node-fetch

解决方案


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)

推荐阅读