0

我正在尝试access_token使用 axios 使用客户端凭据从 keycloak 获取。但是,当我使用 axios 发布请求获取 access_token 时,出现 400 错误。

我没有使用邮递员测试我的客户端凭据,它确实返回了 access__token 但是,在 NextJS 应用程序中使用时,我收到 400 错误:

目前在我的_app.tsx文件中,我有以下方法:

const getToken = () => {
  let token: string = undefined;
  const realm = process.env.NEXT_PUBLIC_KEYCLOAK_REALM;
  const keycloakClientSecret = process.env.NEXT_PUBLIC_KEYCLOAK_BEARER_CLIENT_SECRET;
  const kcTokenEndpoint = `http://localhost:8080/auth/realms/${realm}/protocol/openid-connect/token`;

  axios({
    method: 'POST',
    url: kcTokenEndpoint,
    data: {
      client_id: 'keycloak-token-bearer', // create client in keycloak with same name
      client_secret: keycloakClientSecret,
      grant_type: 'client_credentials',
    },
    headers: {
      'Content-type': 'application/x-www-form-urlencoded',
    },
    withCredentials: true,
  })
    .then(response => {
      token = (response as any)?.access_token;
    })
    .catch(error => {
      token = undefined;
    });

  return token;
};

我看到返回 a400 (Bad Request) error 当我检查响应时,我看到以下内容:

error   "invalid_request"
error_description   "Missing form parameter: grant_type"
4

1 回答 1

1

axios.post是一个异步操作。目前你总是undefined从你的函数中返回,因为你没有等待axios请​​求解决。

如果你有异步函数,那么你只能从它返回一个承诺。

所以你要么需要这样做:

  // Add return here
  return axios({
    method: 'POST',
    url: kcTokenEndpoint,
    data: {
      client_id: 'keycloak-token-bearer', // create client in keycloak with same name
      client_secret: keycloakClientSecret,
      grant_type: 'client_credentials',
    },
    headers: {
      'Content-type': 'application/x-www-form-urlencoded',
    },
    withCredentials: true,
  })
    .then(response => {
      // Return token here
      return (response as any)?.access_token;
    })

或者发出getToken函数asyncawaitaxios 请求:

const getToken = async () => {
  const realm = process.env.NEXT_PUBLIC_KEYCLOAK_REALM;
  const keycloakClientSecret = process.env.NEXT_PUBLIC_KEYCLOAK_BEARER_CLIENT_SECRET;
  const kcTokenEndpoint = `http://localhost:8080/auth/realms/${realm}/protocol/openid-connect/token`;

  cosnt { response } = await axios({
    method: 'POST',
    url: kcTokenEndpoint,
    data: {
      client_id: 'keycloak-token-bearer', // create client in keycloak with same name
      client_secret: keycloakClientSecret,
      grant_type: 'client_credentials',
    },
    headers: {
      'Content-type': 'application/x-www-form-urlencoded',
    },
    withCredentials: true,
  })

  return response.access_token;
};

显然现在你也需要await getToken运行或使用then(...)

于 2021-07-09T17:05:34.823 回答