公司希望我把公司的keycloak作为新项目的一种第三方登录方式时,就像微信,google,github,使用keycloak上的账户资源
因此,先需要跟公司keyclock管理员联系,让他把各个端点url,keycloak颁发的client_id和client_secret都给你,并让三方管理员设置好我们需要重定向的地址后,就可以通过postman模拟整个操作过程了。
首先根据你自己的端点url以及client_id和redirect_uri可以确定出,访问到keyclock登录页的url
https://xxxxxxxxx/realms/ms/protocol/openid-connect/auth?
response_type=code&
client_id=xxxxxxx&
scope=openid%20profile%20roles%20email&
redirect_uri=http://127.0.0.1:5003/
- 客户端ID client_id=aaa(需要找管理员拿到)
- 授权类型 response_type=code
- scope类型 scope=openid
- 三方应用的回调地址 redirect_uri(需要先让管理员绑定,再找管理员拿到)
- https://xxxxxxxxx/realms/ms/protocol/openid-connect/auth? (需要找管理员拿到)
然后根据这个地址就可以访问到登录页
登录所有步骤走完之后,就会跳转都我的127.0.0.1:5003页面
登录成功后,重定向到你的系统中,并带着code和redirect_uri及session等信息。
http://127.0.0.1:5003/?
session_state=406a3a77-0e69-460d-be9b-5488868204b2&
iss=https%3A%2F%2Fauth.successfulmatch.com%2Frealms%2Fms&
code=5321e12c-2de8-4201-9c73-a73ca6051bb2.406a3a77-0e69-460d-be9b-5488868204b2.83dee5bc-b3da-4991-902f-bae1214cfcb9
- 三方应用系统的回调地址:redirect_uri
- 授权码:code
- 会话标识:session_state
然后直接拿着code去postman请求
https://xxxxxx/realms/ms/protocol/openid-connect/token
请求完成可以拿到响应内容为access_token和refresh_token
通过access_token来获取用户信息,正常返回200,如果是返回401,你需要从新获取
获取用户信息:/auth/realms/xxx/open/userinfo。
其中带上access_token
就可以正常拿到用户信息了。然后根据自己的流程就可以做相应的操作了
具体流程图其实就是
参考keycloak~作为第三方登录的对接标准 - 张占岭 - 博客园 (cnblogs.com)
当然上面只是用postman来拿信息,你也可以直接解析第二步返回回来的一些token值,也可以直接拿到对应的信息。
以下是我用laravel写的,通过code拿去用户信息的接口
class KeyclockService extends BaseService
{
public function handleAuthorizationCode(): array
{
$code = $this->input['code'];
$client = new Client();
$response = $client->post('https://auth.successfulmatch.com/realms/ms/protocol/openid-connect/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'code' => $code,
'client_id' => 'xxxxxx',
'client_secret' => 'xxxxxxxx',
'redirect_uri' => 'http://127.0.0.1:5003/'
]
]);
$body = json_decode($response->getBody(), true);
$accessToken = $body['access_token'];
$refreshToken = $body['refresh_token'];
$idToken = $body['id_token'];
$decodedIdToken = $this->decodeIdToken($idToken);
$decodedAccessToken = $this->decodeIdToken($accessToken);
$decodedRefreshToken = $this->decodeIdToken($refreshToken);
$userId = $decodedIdToken['sub']; // 用户的唯一标识符
$userName = $decodedIdToken['preferred_username']; // 用户名
return [
'$decodedIdToken' => $decodedIdToken,
'$decodedAccessToken' => $decodedAccessToken,
'$decodedRefreshToken' => $decodedRefreshToken,
'user_id' => $userId,
'user_name' => $userName,
'access_token' => $accessToken,
'id_token' => $idToken
];
}
private function decodeIdToken($idToken)
{
$tokenParts = explode('.', $idToken);
$tokenPayload = base64_decode($tokenParts[1]);
return json_decode($tokenPayload, true);
}
}