mohamed amine salah Asked: 2024-11-19 01:06:11 +0800 CST2024-11-19 01:06:11 +0800 CST 2024-11-19 01:06:11 +0800 CST 响应中的 id_token 缺少 nonce 772 我使用 Keycloak 21 进行身份验证,但遇到了一个问题,即调用 /token 后返回的 id_token 中不包含 nonce 值。我在 /auth 请求中传递了 nonce, keycloak 1 个回答 Voted Best Answer Bench Vue 2024-11-19T11:06:50+08:002024-11-19T11:06:50+08:00 你可以通过这个方法 URL GET ${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth? query parameters client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: 'code', scope: 'openid', nonce: nonce, 然后在回调URL获取ID token 步骤 步骤 1:通过 docker compose 启动 Keycloak v21 version: '3.9' services: keycloak: image: quay.io/keycloak/keycloak:21.1.2 container_name: keycloak command: - start-dev environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin KC_DB: postgres KC_DB_URL_HOST: keycloak-db KC_DB_URL_DATABASE: keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: keycloakpassword KC_HOSTNAME: localhost ports: - "8080:8080" depends_on: - keycloak-db volumes: - keycloak-data:/opt/keycloak/data keycloak-db: image: postgres:15 container_name: keycloak-db environment: POSTGRES_USER: keycloak POSTGRES_PASSWORD: keycloakpassword POSTGRES_DB: keycloak ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data volumes: keycloak-data: postgres-data: 更多详细信息请参阅此处 步骤 2. 创建 my-realm、my-cleint 和 user1 回调网址 http://localhost:3000/callback 从 UI 复制客户端机密 username是 User1,password是 1234 步骤 3:运行 Express 服务器 install dependencies npm install express axios querystring [email protected] crypto demo.js const express = require('express'); const axios = require('axios'); const crypto = require('crypto'); const querystring = require('querystring'); const jwtDecode = require('jwt-decode'); const app = express(); const PORT = 3000; //replace your Redirect PORT // Keycloak Configuration const KEYCLOAK_URL = 'http://localhost:8080'; // Replace with your Keycloak server URL const REALM = 'my-realm'; // Replace with your realm name const CLIENT_ID = 'my-client'; // Replace with your client ID const CLIENT_SECRET = '[your my-client password]'; // Replace if your client is confidential const REDIRECT_URI = 'http://localhost:3000/callback'; // Replace with your app's redirect URI // Generate a random nonce const generateNonce = () => crypto.randomBytes(16).toString('base64'); // Store the nonce temporarily (use a proper session store in production) let storedNonce; // Routes // 1. Start Authorization app.get('/login', (req, res) => { const nonce = generateNonce(); storedNonce = nonce; // Save the nonce for validation later const authUrl = `${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth?` + querystring.stringify({ client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: 'code', scope: 'openid', nonce: nonce, }); res.redirect(authUrl); // Redirect user to Keycloak login }); // Step 2. Handle Callback for get tokens app.get('/callback', async (req, res) => { const { code } = req.query; if (!code) { return res.status(400).send('Authorization code not found!'); } try { const tokenResponse = await axios.post( `${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token`, querystring.stringify({ grant_type: 'authorization_code', code: code, redirect_uri: REDIRECT_URI, client_id: CLIENT_ID, client_secret: CLIENT_SECRET, }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ); const { id_token } = tokenResponse.data; // Decode and validate the ID token const decodedToken = jwtDecode(id_token); if (decodedToken.nonce !== storedNonce) { return res.status(401).send('Invalid nonce!'); } res.send({ message: 'Login successful!', id_token: decodedToken, }); } catch (error) { console.error('Error exchanging code for tokens:', error); res.status(500).send('Error exchanging code for tokens.'); } }); // Start the Express server app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); }); run it node demo.js 步骤4 通过浏览器获取token http://localhost:3000/login 结果
你可以通过这个方法
URL
query parameters
然后在回调URL获取ID token
步骤
步骤 1:通过 docker compose 启动 Keycloak v21
更多详细信息请参阅此处
步骤 2. 创建 my-realm、my-cleint 和 user1
回调网址
从 UI 复制客户端机密
username
是 User1,password
是 1234步骤 3:运行 Express 服务器
install dependencies
demo.js
run it
步骤4 通过浏览器获取token
结果