Keycloak缺少表单参数:grant_type

66

我在本地机器上运行了Keycloak独立版。

我创建了一个名为'spring-test'的新领域,然后创建了一个名为'login-app'的新客户端。

根据REST文档:

POST: http://localhost:8080/auth/realms/spring-test/protocol/openid-connect/token

{
    "client_id": "login-app",
    "username": "user123",
    "password": "pass123",
    "grant_type": "password"
}

应该给我JWT令牌,但响应为“坏请求”

{
    "error": "invalid_request",
    "error_description": "Missing form parameter: grant_type"
}

我认为我的配置中缺少了某些内容。

编辑: 我之前使用的是json格式的主体,但应该是application/x-www-form-urlencoded

以下主体有效:

token_type_hint:access_token&token:{token}&client_id:{client_id}&client_secret:{client_secret}
9个回答

81

您应该将数据通过POST请求发送,并将Content-Type头的值设置为application/x-www-form-urlencoded,而不是json。


6
即使我将内容类型设置为urlencoded,问题仍然存在: curl -d '{"grant_type": "password", "username": "user", "password": "pass", "client_id": "login-app"}' -H "Content-Type: application/x-www-form-urlencoded" -X POST "http://localhost:8082/auth/realms/ina-dev/protocol/openid-connect/token" {"error":"invalid_request","error_description":"缺少表单参数:grant_type"} - Ognjen Mišić
2
因为您发送的是JSON数据,所以应该使用"-d"参数加上"param1=value1&param2=value2"的语法。 - ipave
2
这个不起作用。你怎么在Postman中设置那个“-d”东西,@ipave? - Avión
3
@Avión 这里是一个链接 - https://learning.getpostman.com/docs/postman/sending_api_requests/requests/#urlencoded - ipave
1
谢谢,我正在发送“multipart/form-data; boundary=--------------------------616846104444017186133807” - masterxilo

22

使用Curl

curl -X POST \
http://localhost:8080/auth/realms/api-gateway/protocol/openid-connect/token \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Length: 73' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Cookie: JSESSIONID=F8CD240FF046572F864DC37148E51128.a139df207ece;   JSESSIONID=65D31B82F8C5FCAA5B1577DA03B4647C' \
-H 'Host: localhost:8080' \
-H 'Postman-Token: debc4f90-f555-4769-b392-c1130726a027,d5087d9f-9253-48bd-bb71-fda1d4558e4d' \
-H 'User-Agent: PostmanRuntime/7.15.2' \
-H 'cache-control: no-cache' \
-d 'grant_type=password&client_id=api-gateway&username=admin&password=temp123'

通过 Postman(选择 x-www-form-urlencoded 选项以使用参数)

在此输入图片描述


4
别忘了填写 client_secret - aswzen

21

对于那些通过搜索寻找 JavaScript 解决方案而来的人。

这是一个使用 axios,将 code 替换为 access_token 并使用 keycloak 权限机构的示例。

发送请求:


const params = new URLSearchParams({

    grant_type: 'authorization_code',
    client_id: 'client-id-here',
    code: 'code-from-previous-redirect',
    redirect_uri: location.protocol + '//' + location.host

});

axios({

    method: 'post',
    url: 'https://my-keycloak.authority/token',
    data: params.toString(),
    config: {
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }

}).then(response => {

    console.log(response.data);

}).catch(error => {

    console.error(error);

});

您需要发送一个包含参数的 URL 编码字符串的 POST 请求到请求体中。 FormData 对象无法使用。

有一种简单的方法可以在不使用查询字符串的情况下获取令牌。const config = { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }; const formParameter = client_id=KEYCLOAK_CLIENT_ID&client_secret=KEYCLOAK_CLIENT_SECRET&grant_type=KEYCLOAK_API_GRANT_TYPE; axios.post(REQUEST_URL,formParameter,config); - Syam Sankar
Pavan J在StackOverflow上发布了一个回答,说:“感谢@marc提供的解决方案,它很有效!我在很多论坛中一直在寻找这个解决方案。PS:grant_type中有一个错别字:'authorization_code'(缺少闭引号)”。 - Scratte
查询字符串现在已被弃用。 https://github.com/nodejs/node/blob/v17.0.0/lib/querystring.js - Sudarshan
由于@sudarshan指出了queryString已经被弃用,因此我们可以使用URLSearchParams来代替。在这段代码片段中,我们可以将new URLSearchParams(params)替换为queryString.stringify(params)。URLSearchParams应该支持新版本的Node和浏览器。如果您的Node版本不支持它,我们可以使用polyfill。 - Jonathan Beadle

16

对于那些使用curl出现问题的人,curl命令如下

curl -d "client_secret=<client-secret>" -d "client_id=<client-id>" -d "username=<username>" -d "password=<password>" -d "grant_type=password" "http://localhost:8080/auth/realms/<realm-name>/protocol/openid-connect/token"

curl命令可以在没有Content-Type头的情况下正常工作。


0
在SOAPUI测试中,我遇到了类似的问题。我们不应该POST一个JSON。当我清空'Media Type'并勾选了'PostQueryString'复选框时,这个问题得到了解决。'Media Type'框会自动设置为'www-form-urlencoded'。通过点击加号,在顶部添加属性。

enter image description here


0

错误类型: { "error": "invalid_request", "error_description": "缺少表单参数:grant_type" }

大家好,如果您在使用ARC进行POST请求测试keycloak时遇到“grant_type”错误,可以对参数进行以下修改:将HEADER设置为“content_type”,并将值设置为“application/x-www-form-urlencoded”


1
类似的答案已经存在: https://dev59.com/jlQJ5IYBdhLWcg3weVu7#53795226 - Amit Tamrakar

0
如果您仍然遇到这个问题,请仔细检查您的客户端和用户是否属于POST请求中的领域。

0

这是一个示例 CURL 命令

curl -X POST \
  http://localhost:8080/auth/realms/your_realm_name/protocol/openid-connect/token \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 69' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Cookie: KC_RESTART=' \
  -H 'Host: localhost:8080' \
  -H 'Postman-Token: 88f38aa0-8659-4b37-a2aa-d6b92177bdc2,29c4e7db-51f4-48d1-b6d5-daab06b68ab4' \
  -H 'User-Agent: PostmanRuntime/7.20.1' \
  -H 'cache-control: no-cache' \
  -d 'client_id=my-app&username=admin&password=admin123&grant_type=password'

0

扩展提供的解决方案 已接受答案

以下代码直接采用application/x-www-form-urlencoded格式

`grant_type=${encodeURIComponent('authorization_code')}&code=${encodeURIComponent(this.authorizationCode)}&redirect_uri=${encodeURIComponent(redirectUri)}&client_id=${encodeURIComponent(clientId)}&code_verifier=${encodeURIComponent(codeVerifier)}`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接