Flask Integration#
This documentation covers OAuth 2.0 and OpenID Connect Client support for Flask. Looking for OAuth 2.0 server?
Flask OAuth client shares a similar API with Flask-OAuthlib, you can transfer your code from Flask-OAuthlib to Authlib with ease.
Create a registry with OAuth object:
from authlib.integrations.flask_client import OAuth
oauth = OAuth(app)
You can also initialize it later with init_app() method:
oauth = OAuth()
oauth.init_app(app)
The common use case for OAuth is authentication, e.g. let your users log in with Twitter, GitHub, Google etc.
Important
Please read Web Clients at first. Authlib has a shared API design among framework integrations, learn them from Web Clients.
Configuration#
Authlib Flask OAuth registry can load the configuration from Flask app.config
automatically. Every key-value pair in .register can be omitted. They can be
configured in your Flask App configuration. Config keys are formatted as
{name}_{key} in uppercase, e.g.
TWITTER_CLIENT_ID |
Twitter Consumer Key |
TWITTER_CLIENT_SECRET |
Twitter Consumer Secret |
TWITTER_REQUEST_TOKEN_URL |
URL to fetch OAuth request token |
If you register your remote app as oauth.register('example', ...), the
config keys would look like:
EXAMPLE_CLIENT_ID |
OAuth Consumer Key |
EXAMPLE_CLIENT_SECRET |
OAuth Consumer Secret |
EXAMPLE_ACCESS_TOKEN_URL |
URL to fetch OAuth access token |
Here is a full list of the configuration keys:
{name}_CLIENT_ID: Client key of OAuth 1, or Client ID of OAuth 2{name}_CLIENT_SECRET: Client secret of OAuth 2, or Client Secret of OAuth 2{name}_REQUEST_TOKEN_URL: Request Token endpoint for OAuth 1{name}_REQUEST_TOKEN_PARAMS: Extra parameters for Request Token endpoint{name}_ACCESS_TOKEN_URL: Access Token endpoint for OAuth 1 and OAuth 2{name}_ACCESS_TOKEN_PARAMS: Extra parameters for Access Token endpoint{name}_AUTHORIZE_URL: Endpoint for user authorization of OAuth 1 or OAuth 2{name}_AUTHORIZE_PARAMS: Extra parameters for Authorization Endpoint.{name}_API_BASE_URL: A base URL endpoint to make requests simple{name}_CLIENT_KWARGS: Extra keyword arguments for OAuth1Session or OAuth2Session
We suggest that you keep ONLY {name}_CLIENT_ID and {name}_CLIENT_SECRET in
your Flask application configuration.
Accessing OAuth Resources#
There is no request in accessing OAuth resources either. Just like above,
we don’t need to pass the request parameter, everything is handled by Authlib
automatically:
from flask import render_template
@app.route('/github')
def show_github_profile():
resp = oauth.github.get('user')
resp.raise_for_status()
profile = resp.json()
return render_template('github.html', profile=profile)
In this case, our fetch_token could look like:
from your_project import current_user
def fetch_token(name):
token = OAuth2Token.find(
name=name,
user=current_user,
)
return token.to_token()
# initialize the OAuth registry with this fetch_token function
oauth = OAuth(fetch_token=fetch_token)
You don’t have to pass token, you don’t have to pass request. That
is the fantasy of Flask.
Auto Update Token via Signal#
Instead of defining an update_token method and passing it into the OAuth registry,
it is also possible to use a signal to listen for token updating.
Before using the signal, make sure you have installed the blinker library:
$ pip install blinker
Connect the token_update signal:
from authlib.integrations.flask_client import token_update
@token_update.connect_via(app)
def on_token_update(sender, name, token, refresh_token=None, access_token=None):
if refresh_token:
item = OAuth2Token.find(name=name, refresh_token=refresh_token)
elif access_token:
item = OAuth2Token.find(name=name, access_token=access_token)
else:
return
# update old token
item.access_token = token['access_token']
item.refresh_token = token.get('refresh_token')
item.expires_at = token['expires_at']
item.save()
Flask OpenID Connect Client#
An OpenID Connect client is no different than a normal OAuth 2.0 client. When
registered with openid scope, the built-in Flask OAuth client will handle everything
automatically:
oauth.register(
'google',
...
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={'scope': 'openid profile email'}
)
When we get the returned token:
token = oauth.google.authorize_access_token()
There should be a id_token in the response. Authlib has called .parse_id_token
automatically, we can get userinfo in the token:
userinfo = token['userinfo']
RP-Initiated Logout#
To implement OpenID Connect RP-Initiated Logout, use the logout_redirect method
to redirect users to the provider’s end session endpoint:
@app.route('/logout')
def logout():
# Retrieve the ID token you stored during login
id_token = session.pop('id_token', None)
return oauth.google.logout_redirect(
post_logout_redirect_uri=url_for('logged_out', _external=True),
id_token_hint=id_token,
)
@app.route('/logged-out')
def logged_out():
state_data = oauth.google.validate_logout_response()
return 'You have been logged out.'
The logout_redirect method accepts:
post_logout_redirect_uri: Where to redirect after logout (must be registered with the provider)id_token_hint: The ID token previously issued (recommended)state: Opaque value for CSRF protection (auto-generated if not provided)client_id: OAuth 2.0 Client Identifier (optional)logout_hint: Hint about the user logging out (optional)ui_locales: Preferred languages for the logout UI (optional)
Note
You must store the id_token during login to use it later for logout.
The id_token is available in token['id_token'] after calling
authorize_access_token().
Examples#
Here are some example projects for you to learn Flask OAuth 2.0 client integrations: