|
1 | 1 | """Python Flask WebApp Auth0 integration example |
2 | 2 | """ |
3 | | -from functools import wraps |
| 3 | + |
4 | 4 | import json |
5 | 5 | from os import environ as env |
6 | | -from werkzeug.exceptions import HTTPException |
7 | | - |
8 | | -from dotenv import load_dotenv, find_dotenv |
9 | | -from flask import Flask |
10 | | -from flask import jsonify |
11 | | -from flask import redirect |
12 | | -from flask import render_template |
13 | | -from flask import session |
14 | | -from flask import url_for |
15 | | -from authlib.integrations.flask_client import OAuth |
16 | | -from six.moves.urllib.parse import urlencode |
| 6 | +from urllib.parse import quote_plus, urlencode |
17 | 7 |
|
18 | | -import constants |
| 8 | +from authlib.integrations.flask_client import OAuth |
| 9 | +from dotenv import find_dotenv, load_dotenv |
| 10 | +from flask import Flask, redirect, render_template, session, url_for |
19 | 11 |
|
20 | 12 | ENV_FILE = find_dotenv() |
21 | 13 | if ENV_FILE: |
22 | 14 | load_dotenv(ENV_FILE) |
23 | 15 |
|
24 | | -AUTH0_CALLBACK_URL = env.get(constants.AUTH0_CALLBACK_URL) |
25 | | -AUTH0_CLIENT_ID = env.get(constants.AUTH0_CLIENT_ID) |
26 | | -AUTH0_CLIENT_SECRET = env.get(constants.AUTH0_CLIENT_SECRET) |
27 | | -AUTH0_DOMAIN = env.get(constants.AUTH0_DOMAIN) |
28 | | -AUTH0_BASE_URL = 'https://' + AUTH0_DOMAIN |
29 | | -AUTH0_AUDIENCE = env.get(constants.AUTH0_AUDIENCE) |
30 | | - |
31 | | -app = Flask(__name__, static_url_path='/public', static_folder='./public') |
32 | | -app.secret_key = constants.SECRET_KEY |
33 | | -app.debug = True |
34 | | - |
35 | | - |
36 | | -@app.errorhandler(Exception) |
37 | | -def handle_auth_error(ex): |
38 | | - response = jsonify(message=str(ex)) |
39 | | - response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) |
40 | | - return response |
| 16 | +app = Flask(__name__) |
| 17 | +app.secret_key = env.get("APP_SECRET_KEY") |
41 | 18 |
|
42 | 19 |
|
43 | 20 | oauth = OAuth(app) |
44 | 21 |
|
45 | | -auth0 = oauth.register( |
46 | | - 'auth0', |
47 | | - client_id=AUTH0_CLIENT_ID, |
48 | | - client_secret=AUTH0_CLIENT_SECRET, |
49 | | - api_base_url=AUTH0_BASE_URL, |
50 | | - access_token_url=AUTH0_BASE_URL + '/oauth/token', |
51 | | - authorize_url=AUTH0_BASE_URL + '/authorize', |
| 22 | +oauth.register( |
| 23 | + "auth0", |
| 24 | + client_id=env.get("AUTH0_CLIENT_ID"), |
52 | 25 | client_kwargs={ |
53 | | - 'scope': 'openid profile email', |
| 26 | + "scope": "openid profile email", |
54 | 27 | }, |
| 28 | + server_metadata_url=f'https://{env.get("AUTH0_DOMAIN")}/.well-known/openid-configuration', |
55 | 29 | ) |
56 | 30 |
|
57 | 31 |
|
58 | | -def requires_auth(f): |
59 | | - @wraps(f) |
60 | | - def decorated(*args, **kwargs): |
61 | | - if constants.PROFILE_KEY not in session: |
62 | | - return redirect('/login') |
63 | | - return f(*args, **kwargs) |
64 | | - |
65 | | - return decorated |
66 | | - |
67 | | - |
68 | 32 | # Controllers API |
69 | | -@app.route('/') |
| 33 | +@app.route("/") |
70 | 34 | def home(): |
71 | | - return render_template('home.html') |
| 35 | + return render_template( |
| 36 | + "home.html", |
| 37 | + session=session.get("user"), |
| 38 | + pretty=json.dumps(session.get("user"), indent=4), |
| 39 | + ) |
72 | 40 |
|
73 | 41 |
|
74 | | -@app.route('/callback') |
75 | | -def callback_handling(): |
76 | | - auth0.authorize_access_token() |
77 | | - resp = auth0.get('userinfo') |
78 | | - userinfo = resp.json() |
| 42 | +@app.route("/callback", methods=["GET", "POST"]) |
| 43 | +def callback(): |
| 44 | + token = oauth.auth0.authorize_access_token() |
| 45 | + session["user"] = token |
| 46 | + return redirect("/") |
79 | 47 |
|
80 | | - session[constants.JWT_PAYLOAD] = userinfo |
81 | | - session[constants.PROFILE_KEY] = { |
82 | | - 'user_id': userinfo['sub'], |
83 | | - 'name': userinfo['name'], |
84 | | - 'picture': userinfo['picture'] |
85 | | - } |
86 | | - return redirect('/dashboard') |
87 | 48 |
|
88 | | - |
89 | | -@app.route('/login') |
| 49 | +@app.route("/login") |
90 | 50 | def login(): |
91 | | - return auth0.authorize_redirect(redirect_uri=AUTH0_CALLBACK_URL, audience=AUTH0_AUDIENCE) |
| 51 | + return oauth.auth0.authorize_redirect( |
| 52 | + redirect_uri=url_for("callback", _external=True) |
| 53 | + ) |
92 | 54 |
|
93 | 55 |
|
94 | | -@app.route('/logout') |
| 56 | +@app.route("/logout") |
95 | 57 | def logout(): |
96 | 58 | session.clear() |
97 | | - params = {'returnTo': url_for('home', _external=True), 'client_id': AUTH0_CLIENT_ID} |
98 | | - return redirect(auth0.api_base_url + '/v2/logout?' + urlencode(params)) |
99 | | - |
100 | | - |
101 | | -@app.route('/dashboard') |
102 | | -@requires_auth |
103 | | -def dashboard(): |
104 | | - return render_template('dashboard.html', |
105 | | - userinfo=session[constants.PROFILE_KEY], |
106 | | - userinfo_pretty=json.dumps(session[constants.JWT_PAYLOAD], indent=4)) |
| 59 | + return redirect( |
| 60 | + "https://" |
| 61 | + + env.get("AUTH0_DOMAIN") |
| 62 | + + "/v2/logout?" |
| 63 | + + urlencode( |
| 64 | + { |
| 65 | + "returnTo": url_for("home", _external=True), |
| 66 | + "client_id": env.get("AUTH0_CLIENT_ID"), |
| 67 | + }, |
| 68 | + quote_via=quote_plus, |
| 69 | + ) |
| 70 | + ) |
107 | 71 |
|
108 | 72 |
|
109 | 73 | if __name__ == "__main__": |
110 | | - app.run(host='0.0.0.0', port=env.get('PORT', 3000)) |
| 74 | + app.run(host="0.0.0.0", port=env.get("PORT", 3000)) |
0 commit comments