From d33c1ea22f6aa3f49b044a5fb5799475261f6d70 Mon Sep 17 00:00:00 2001 From: Alexis Luque Date: Fri, 6 Apr 2018 16:50:44 -0300 Subject: [PATCH 1/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index c0dd83aff4..66040ea7c4 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -1,7 +1,7 @@ --- title: Login default: true -description: This tutorial demonstrates how to use the Python OAuthlib to add authentication and authorization to your web app +description: This tutorial demonstrates how to use the Python Authlib to add authentication and authorization to your web app budicon: 448 --- @@ -16,7 +16,7 @@ You can get started by either downloading the complete sample or following the t 'Flask 0.10.1 and up', 'Python-dotenv 0.6.5 and up', 'Requests 2.3.0 and up', - 'Flask-oauthlib 0.9.4 and up', + 'Authlib 0.6', 'Six 1.10.0 and up' ] }) %> @@ -25,7 +25,7 @@ You can get started by either downloading the complete sample or following the t ## Add the Dependencies -This example uses [Flask](http://flask.pocoo.org) and the [Flask OAuthlib](https://flask-oauthlib.readthedocs.io) OAuth client library. +This example uses [Flask](http://flask.pocoo.org) and the [Authlib](https://github.com/lepture/authlib) OAuth library. Add the following dependencies to your `requirements.txt` and run `pip install -r requirements.txt`. @@ -35,11 +35,11 @@ Add the following dependencies to your `requirements.txt` and run `pip install - flask python-dotenv requests -flask-oauthlib +authlib six ``` -## Initialize Flask-OAuthlib +## Initialize Authlib With `OAuth` you call the authorize endpoint of the Authentication API and redirect your users to the [login page](/hosted-pages/login). This way, you will be implementing the [authorization code grant flow](/api-auth/tutorials/authorization-code-grant), so you will obtain a `code`. Create a file named `server.py`, and instantiate a client with your client keys, scopes, and OAuth endpoints. @@ -47,33 +47,42 @@ Create a file named `server.py`, and instantiate a client with your client keys, ```python # /server.py +from functools import wraps +import json +from os import environ as env +from werkzeug.exceptions import HTTPException + +from dotenv import load_dotenv, find_dotenv from flask import Flask +from flask import jsonify +from flask import redirect from flask import render_template -from flask import request -from flask_oauthlib.client import OAuth +from flask import session +from flask import url_for +from authlib.flask.client import OAuth +from six.moves.urllib.parse import urlencode +import requests app = Flask(__name__) oauth = OAuth(app) -auth0 = oauth.remote_app( + +auth0 = oauth.register( 'auth0', - consumer_key='${account.clientId}', - consumer_secret='YOUR_CLIENT_SECRET', - request_token_params={ + client_id='${account.clientId}', + client_secret='YOUR_CLIENT_SECRET', + api_base_url='https://${account.namespace}', + access_token_url='https://${account.namespace}/oauth/token', + authorize_url='https://${account.namespace}/authorize', + client_kwargs={ 'scope': 'openid profile', - 'audience': 'https://' + '${account.namespace}' + '/userinfo' }, - base_url='https://%s' % '${account.namespace}', - access_token_method='POST', - access_token_url='/oauth/token', - authorize_url='/authorize', ) ``` ## Add the Auth0 Callback Handler -This handler exchanges the `code` that Auth0 sends to the callback URL for an `access_token` -and an `id_token`. +This handler exchanges the `code` that Auth0 sends to the callback URL for an `access_token` and an `id_token`. The `id_token` is a [JWT](/jwt) that contains the user profile information for the requested [OIDC Conformant claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) , to get the information from it you have to decode and validate its signature. After the user information is obtained, store then in the flask `session`. @@ -84,40 +93,35 @@ The `id_token` is a [JWT](/jwt) that contains the user profile information for t @app.route('/callback') def callback_handling(): # Handles response from token endpoint - resp = auth0.authorized_response() - if resp is None: - raise Exception('Access denied: reason=%s error=%s' % ( - request.args['error_reason'], - request.args['error_description'] - )) - - url = 'https://' + AUTH0_DOMAIN + '/userinfo' + resp = auth0.authorize_access_token() + + url = 'https://${account.namespace}/userinfo' headers = {'authorization': 'Bearer ' + resp['access_token']} resp = requests.get(url, headers=headers) userinfo = resp.json() - + # Store the tue user information in flask session. - session[constants.JWT_PAYLOAD] = userinfo - - session[constants.PROFILE_KEY] = { + session['jwt_payload'] = userinfo + + session['profile'] = { 'user_id': userinfo['sub'], 'name': userinfo['name'], 'picture': userinfo['picture'] } - + return redirect('/dashboard') ``` ## Trigger Authentication -Add a `/login` route that uses the `Flask-OAuthlib` client instance to redirect the user to the [login page](/hosted-pages/login). +Add a `/login` route that uses the `Authlib` client instance to redirect the user to the [hosted login page](/hosted-pages/login). ```python # /server.py @app.route('/login') def login(): - return auth0.authorize(callback='${account.callback}') + return auth0.authorize_redirect(redirect_uri='YOUR_CALLBACK_URL', audience='https://${account.namespace}/userinfo') ``` Create a `home.html` file in a `/template` folder. Add a link to the `/login` route. @@ -175,7 +179,7 @@ def requires_auth(f): ## Showing the User Profile -Add a `/dashboard` route to `server.py` that will render the user information stored in the Flask session. +Add a `/dashboard` route to `server.py` that will render the user information stored in the Flask session. Decorate it with `@requires_auth`. It will only be accessible if the user has been authenticated. @@ -186,11 +190,11 @@ Decorate it with `@requires_auth`. It will only be accessible if the user has be @requires_auth def dashboard(): return render_template('dashboard.html', - userinfo=session[constants.PROFILE_KEY], - userinfo_pretty=json.dumps(session[constants.JWT_PAYLOAD], indent=4)) + userinfo=session['profile'], + userinfo_pretty=json.dumps(session['jwt_payload'], indent=4)) ``` -Add a `dashboard.html` file in a `/template` folder to display the user information. +Add a `dashboard.html` file in a `/template` folder to display the user information. Add a link to allow users to Log Out. From af188fdcf56675610a566c432089e2be2b2361a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 16 Apr 2018 22:39:24 -0300 Subject: [PATCH 2/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index a4514a48f1..06debcdf69 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -1,7 +1,7 @@ --- title: Login default: true -description: This tutorial demonstrates how to use the Python Authlib to add authentication and authorization to your web app +description: This tutorial demonstrates how to use the Python Authlib to add authentication and authorization to your web application. budicon: 448 --- From 060c6d337ea3e8fa2c3deda30cb5a9ad7e95f81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 16 Apr 2018 22:43:31 -0300 Subject: [PATCH 3/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index 06debcdf69..5708118da7 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -84,7 +84,7 @@ auth0 = oauth.register( This handler exchanges the `code` that Auth0 sends to the callback URL for an `access_token` and an `id_token`. -The `id_token` is a [JWT](/jwt) that contains the user profile information for the requested [OIDC Conformant claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) , to get the information from it you have to decode and validate its signature. After the user information is obtained, store then in the flask `session`. +The `access_token` will be used to call the `/userinfo` endpoint to get the user profile. After the user information is obtained, store then in the flask `session`. ```python # /server.py From d33d101e1e6a41f9785446fbafa78196603f8e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 16 Apr 2018 22:53:02 -0300 Subject: [PATCH 4/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 1 - 1 file changed, 1 deletion(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index 5708118da7..e0bd79f93a 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -41,7 +41,6 @@ six ## Initialize Authlib -With `OAuth` you call the authorize endpoint of the Authentication API and redirect your users to the [login page](/hosted-pages/login). This way, you will be implementing the [authorization code grant flow](/api-auth/tutorials/authorization-code-grant), so you will obtain a `code`. Create a file named `server.py`, and instantiate an application with your client keys, scopes, and OAuth endpoints. ```python From 81ad4e31ae42bc2b48b42ea0de75f7d5135fddab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 16 Apr 2018 23:08:08 -0300 Subject: [PATCH 5/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index e0bd79f93a..5afda8f452 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -1,7 +1,7 @@ --- title: Login default: true -description: This tutorial demonstrates how to use the Python Authlib to add authentication and authorization to your web application. +description: This tutorial demonstrates how to add authentication and authorization to a Python Web Application built with Flask. budicon: 448 --- From f0729ad86adc44bb6e410ce6de65b921680e1097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 16 Apr 2018 23:47:10 -0300 Subject: [PATCH 6/6] Update 01-login.md --- articles/quickstart/webapp/python/01-login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/quickstart/webapp/python/01-login.md b/articles/quickstart/webapp/python/01-login.md index 5afda8f452..53d5465803 100644 --- a/articles/quickstart/webapp/python/01-login.md +++ b/articles/quickstart/webapp/python/01-login.md @@ -1,7 +1,7 @@ --- title: Login default: true -description: This tutorial demonstrates how to add authentication and authorization to a Python Web Application built with Flask. +description: This tutorial demonstrates how to add authentication and authorization to a Python Web Application built with the Flask framework. budicon: 448 ---