Integrating FusionAuth with Python Flask: A Step-by-Step Guide
Tags: python, flask, oauth, programming
Published: 2023-05-02 18:35:06

[FusionAuth](https://fusionauth.io/) is a powerful identity and access management platform that makes it easy to add authentication and authorization to your applications. In this blog post, we'll explore how to integrate FusionAuth with a Python [Flask](https://flask.palletsprojects.com/en/2.3.x/) application using [OAuth 2.0](https://oauth.net/2/), covering features such as login, displaying user profile information, and logout functionality.

## Prerequisites

Before diving into [the integration](https://github.com/rainleander/fusionauth-python-flask-example), make sure you have the following prerequisites in place:

- Python 3.x installed on your system
- FusionAuth installed and configured (either on your local machine or using the cloud version - I used the local setup)

## Setting Up the Python Flask Application

First, let's set up a basic Python Flask application. Create a new directory for your project and install the required libraries:

```bash
pip install flask requests
```

Next, create a new file called `app.py` in your project directory and add the following code:

```python
from flask import Flask, redirect, request, session, url_for
import requests

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# Replace the following placeholders with your FusionAuth credentials
client_id = 'your_client_id'
client_secret = 'your_client_secret'
fusionauth_url = 'https://your_fusionauth_url'

# ...

if __name__ == '__main__':
    app.run(debug=True)
```

Make sure to replace `'your_secret_key'` with a secure secret key for Flask, and add the appropriate FusionAuth credentials in place of the placeholders.

## Adding Login Functionality

To enable users to log in using FusionAuth, we'll add a new route to our Flask application. Add the following code to `app.py`:

```python
@app.route('/')
def home():
    return f'<a href="{fusionauth_url}/oauth2/authorize?client_id={client_id}&response_type=code&redirect_uri=http://localhost:5000/callback">Login with FusionAuth</a>'
```

This route will display a "Login with FusionAuth" link that directs users to the FusionAuth authorization endpoint. When a user logs in or registers, they will be redirected back to our application with an authorization code.

Next, let's add a callback route to handle the authorization code and exchange it for an access token:

```python
@app.route('/callback')
def callback():
    code = request.args.get('code')
    token_endpoint = f'{fusionauth_url}/oauth2/token'

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    data = {
        'grant_type': 'authorization_code',
        'client_id': client_id,
        'client_secret': client_secret,
        'code': code,
        'redirect_uri': 'http://localhost:5000/callback',
    }

    response = requests.post(token_endpoint, headers=headers, data=data)
    token_response = response.json()
    session['access_token'] = token_response['access_token']

    return redirect(url_for('profile'))
```

In this route, we extract the authorization code from the query parameters and make a POST request to the FusionAuth token endpoint to obtain an access token. We then store the access token in the user's session and redirect them to the profile page.

## Displaying User Profile Information

To display the user's profile information, we'll add a new route called `/profile`. Add the following code to `app.py`:

```python
@app.route('/profile')
def profile():
    access_token = session['access_token']
    userinfo_url = f'{fusionauth_url}/oauth2/userinfo'
    headers = {'Authorization': f'Bearer {access_token}'}
    response = requests.get(userinfo_url, headers=headers)
    user_info = response.json()

    profile_html = f'<h1>Welcome, {user_info["given_name"]} {user_info["family_name"]}!</h1>'
    profile_html += f'<p>Email: {user_info["email"]}</p>'
    profile_html += f'<p><a href="/logout">Logout</a></p>'

    return profile_html
```

This route retrieves the user's profile information from the FusionAuth userinfo endpoint using the stored access token. We then display the user's name and email address, along with a logout link.

## Adding Logout Functionality

To allow users to log out of the application and revoke their access token, we'll add a new route called `/logout`. Add the following code to `app.py`:

```python
@app.route('/logout')
def logout():
    access_token = session.pop('access_token', None)
    if access_token:
        revoke_url = f'{fusionauth_url}/oauth2/revoke'
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        data = {'client_id': client_id, 'token': access_token}
        requests.post(revoke_url, headers=headers, data=data)

    return redirect(url_for('home'))
```

In this route, we remove the access token from the user's session and make a POST request to the FusionAuth revoke endpoint to invalidate the token. Finally, we redirect the user back to the home page.

## Conclusion

In this blog post, we've explored how to integrate FusionAuth with a Python Flask application using OAuth 2.0. With this setup, you can easily add authentication and authorization to your Python applications, and leverage the powerful features of FusionAuth to manage users and their access to your application.

Remember that FusionAuth is a flexible and feature-rich platform that can be customized to fit your specific requirements. Be sure to explore the extensive documentation and various integrations to get the most out of your FusionAuth experience.

Happy coding!