Utoljára aktív 9 months ago

此程式碼展示如何在 Flask 應用中整合 Keycloak,實現使用者認證、登入及使用者資訊取得。

.env Eredeti
1KEYCLOAK_BASE_URL=http://192.168.42.102:8080
2KEYCLOAK_REALM=MyRealm
3KEYCLOAK_CLIENT_ID=my-app
4KEYCLOAK_CLIENT_SECRET=DgL6JibOXWzMWvQ2hZOLoeOcg0IfSVsU
5FLASK_SECRET_KEY=your_flask_secret_key
app.py Eredeti
1from flask import Flask, redirect, url_for, session, request
2from authlib.integrations.flask_client import OAuth
3import os
4from dotenv import load_dotenv
5
6load_dotenv()
7
8app = Flask(__name__)
9app.secret_key = os.getenv("FLASK_SECRET_KEY") # 從環境變數讀取
10
11oauth = OAuth(app)
12
13# 建立 Keycloak 的 OIDC 設定
14# 透過 server_metadata_url 來自動取得 OIDC Discovery 設定
15keycloak = oauth.register(
16 name='keycloak',
17 client_id=os.getenv("KEYCLOAK_CLIENT_ID"),
18 client_secret=os.getenv("KEYCLOAK_CLIENT_SECRET"),
19 server_metadata_url=f"{os.getenv('KEYCLOAK_BASE_URL')}/realms/{os.getenv('KEYCLOAK_REALM')}/.well-known/openid-configuration",
20 client_kwargs={
21 'scope': 'openid profile email', # 根據需求調整
22 }
23)
24
25@app.route('/')
26def homepage():
27 return '歡迎!<a href="/login">使用 Keycloak 登入</a>'
28
29@app.route('/login')
30def login():
31 # 生成一個隨機 nonce,作為一次性驗證令牌
32 nonce = os.urandom(16).hex()
33 session['nonce'] = nonce
34 return keycloak.authorize_redirect(
35 redirect_uri=url_for('auth', _external=True),
36 nonce=nonce
37 )
38
39@app.route('/auth')
40def auth():
41 # 取得 Keycloak 回傳的參數並換取 token
42 token = keycloak.authorize_access_token()
43 nonce = session.get('nonce')
44 user_info = keycloak.parse_id_token(token, nonce=nonce)
45 # 將使用者資訊存入 session,並清除 nonce,避免重複驗證
46 session['user'] = user_info
47 session.pop('nonce', None)
48 # 重導到乾淨的頁面
49 return redirect(url_for('profile'))
50
51@app.route('/profile')
52def profile():
53 user_info = session.get('user')
54 if user_info:
55 return f"歡迎, {user_info.get('name', '使用者')}"
56 return redirect(url_for('homepage'))
57
58if __name__ == '__main__':
59 app.run(debug=True)