|
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