使用Keycloak中的refresh_token刷新access_token

70

如果用户的access_token过期并且用户想要保持登录状态,我需要让用户继续在系统中保持登录状态。如何使用Keycloakrefresh_token获取最新的access_token

我正在使用vert.x上的vertx-auth进行身份验证实现,结合Keycloak。是否可以使用vertx-authKeycloak的REST API刷新access_token?否则还有其他的实现方法吗?

4个回答

156

Keycloak具有REST API,可使用refresh_token创建access_token。这是一个POST端点,使用application/x-www-form-urlencoded

它的外观如下:

Method: POST
URL: https://keycloak.example.com/auth/realms/myrealm/protocol/openid-connect/token
Body type: x-www-form-urlencoded
Form fields:    
client_id : <my-client-name>
grant_type : refresh_token
refresh_token: <my-refresh-token>

这将使用刷新令牌为您提供新的访问令牌。

注意:如果您的刷新令牌已过期,它会抛出400异常,此时您可以让用户重新登录。

在Postman中查看示例,您可以使用此方法开发和对应API。

Postman中的示例


6
我已经尝试了2.5.4版本,但对于此请求仍然需要提供客户端密钥,虽然现在我明白为什么会要求提供客户端密钥,如果提供了刷新令牌的话。 - rrrocky
9
仅当客户端为“机密”客户端时需要客户端秘钥。 “公开”客户端不需要客户端秘钥。 - rrrocky
9
为什么在刷新机密客户端的令牌时需要提供客户端密钥? - Kimble
1
@所有人,为什么刷新令牌是JWT格式?无状态但Google和Auth0使用有状态。 - Panup Pong
1
@Kimble confidential client 在 Keycloak 中用于为应用程序提供服务,其中存储客户端秘钥是安全的。请查看文档(这里)。[https://www.keycloak.org/docs/6.0/server_admin/#oidc-clients] - bck
显示剩余5条评论

7

@maslick 是正确的,您需要提供客户端密钥,此时无需授权标头:

http://localhost:8080/auth/realms/{realm}/protocol/openid-connect/token

enter image description here

如果刷新令牌已过期,则返回如下内容:

enter image description here

如果不添加密钥,则会收到“401 未经授权”的响应,即使刷新令牌是正确的。

enter image description here


3
我刚刚测试了一下,只有当发出令牌的客户端是机密的时候,你才需要客户端密码。 - Matteo

1
延伸Yogendra Mishra的回答。请注意,client_idclient_secret也可以在授权头中发送。
Authorization: Basic ${Base64(<client_id>:<client_secret>)}

这适用于初始令牌调用(不带刷新令牌)和对/openid-connect/token端点的刷新令牌调用。 Basic auth1 在设置身份验证标头后,无需在正文中发送客户端ID和密钥 参考: https://developer.okta.com/docs/reference/api/oidc/#client-secret

1

我尝试使用4.8.2.Final版本,即使使用先前的访问令牌作为“Bearer”,它也会给出以下“unauthorized_client”的提示。 然后我在授权标头中使用了“Basic YXBwLXByb3h5OnNlY3JldA==”。 然后它起作用了,但我仍然不确定我是否做对了。


对于授权头,关键在于服务器在头值中寻找什么。如果这样做有效,则您可能不会出错。 - charliebeckwith
2
你可能正在使用机密客户端,因此需要在请求中包含“client_secret”。 - maslick
3
为什么我必须传递客户端密钥来使用刷新令牌呢?如果我使用机密客户端,为什么任何人都想要使用刷新令牌?我的看法是,Keycloak 应该只通过传递 client_id 和 refresh_token 来返回 access_token,因为它的功能类似于密码。 - ganesan arunachalam

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