timmy gist felülvizsgálása 9 months ago. Revízióhoz ugrás
2 files changed, 64 insertions
.env(fájl létrehozva)
| @@ -0,0 +1,5 @@ | |||
| 1 | + | KEYCLOAK_BASE_URL=http://192.168.42.102:8080 | |
| 2 | + | KEYCLOAK_REALM=MyRealm | |
| 3 | + | KEYCLOAK_CLIENT_ID=my-app | |
| 4 | + | KEYCLOAK_CLIENT_SECRET=DgL6JibOXWzMWvQ2hZOLoeOcg0IfSVsU | |
| 5 | + | FLASK_SECRET_KEY=your_flask_secret_key | |
app.py(fájl létrehozva)
| @@ -0,0 +1,59 @@ | |||
| 1 | + | from flask import Flask, redirect, url_for, session, request | |
| 2 | + | from authlib.integrations.flask_client import OAuth | |
| 3 | + | import os | |
| 4 | + | from dotenv import load_dotenv | |
| 5 | + | ||
| 6 | + | load_dotenv() | |
| 7 | + | ||
| 8 | + | app = Flask(__name__) | |
| 9 | + | app.secret_key = os.getenv("FLASK_SECRET_KEY") # 從環境變數讀取 | |
| 10 | + | ||
| 11 | + | oauth = OAuth(app) | |
| 12 | + | ||
| 13 | + | # 建立 Keycloak 的 OIDC 設定 | |
| 14 | + | # 透過 server_metadata_url 來自動取得 OIDC Discovery 設定 | |
| 15 | + | keycloak = 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('/') | |
| 26 | + | def homepage(): | |
| 27 | + | return '歡迎!<a href="/login">使用 Keycloak 登入</a>' | |
| 28 | + | ||
| 29 | + | @app.route('/login') | |
| 30 | + | def 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') | |
| 40 | + | def 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') | |
| 52 | + | def 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 | + | ||
| 58 | + | if __name__ == '__main__': | |
| 59 | + | app.run(debug=True) | |
Újabb
Régebbi