使用Keycloak API通过授权码换令牌失败,提示unauthorized_client
我用Keycloak给应用做认证,已经成功获取授权码,但调用API换取access token和refresh token时一直失败。
我的代码如下:
async function exchangeAuthorizationCodeForTokens(authorizationCode, clientId, redirectUri, realmName, keycloakUrl) { const tokenEndpoint = `${keycloakUrl}/realms/${realmName}/protocol/openid-connect/token`; const codeVerifier = generateCodeVerifier(); const data = { grant_type: 'authorization_code', client_id: clientId, redirect_uri: redirectUri, code: authorizationCode, code_verifier: codeVerifier }; try { const response = await axios.post(tokenEndpoint, new URLSearchParams(data), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }), // 忽略自签名证书 }); console.log('Token exchange successful'); console.log(response.data); return { access_token: response.data.access_token, refresh_token: response.data.refresh_token, }; } catch (error) { console.error('Token exchange failed:', error.response ? error.response.data : error.message); return false; } }
即便用户和客户端已在Keycloak服务器注册,仍持续收到如下错误:
Token exchange failed: { error: 'unauthorized_client', error_description: 'Invalid client or Invalid client credentials' }
排查与解决办法
1. 补全客户端认证凭据
如果Keycloak客户端设置为机密类型(Confidential),换取令牌时必须携带客户端密钥。修改请求数据,添加client_secret字段:
const data = { grant_type: 'authorization_code', client_id: clientId, client_secret: '你的客户端密钥', // 替换为实际客户端密钥 redirect_uri: redirectUri, code: authorizationCode, code_verifier: codeVerifier };
若客户端是公共类型(Public),确认Keycloak客户端配置中Access Type为public,且相关授权选项正常开启。
2. 复用正确的Code Verifier
PKCE流程中,code_verifier必须是生成授权码时用来生成code_challenge的同一个值,不能每次换令牌时重新生成。需在发起授权请求时保存该值,换令牌时直接复用。
3. 确保Redirect URI完全匹配
Keycloak客户端配置的Valid Redirect URIs必须与代码中redirect_uri完全一致,包括协议、域名、端口、路径,不能有多余字符(比如末尾多一个斜杠)。
4. 使用有效授权码
授权码仅可使用一次,且有效期较短(默认几分钟)。确保使用的是刚获取的未过期、未使用过的授权码。
5. 校验客户端ID正确性
检查传入的clientId与Keycloak后台客户端的Client ID完全一致,注意大小写、特殊字符不能有偏差。
内容的提问来源于stack exchange,提问作者nix86
相关产品推荐
相关产品推荐

