Skip to content

Flask Backend Integration

PropelAuth offers an end-to-end managed user authentication library for seamless integration into your Flask application. This guide will show you how to connect the PropelAuth library to your backend. For the full Flask Library Reference, click here.

Quick example

The following example creates a route which can only be accessed from logged-in users.

from flask import Flask
from propelauth_flask import init_auth, current_user

app = Flask(__name__)
auth = init_auth("YOUR_AUTH_URL", #(1)
                 "YOUR_API_KEY") #(2)

@app.route("/api/whoami")
@auth.require_user
def who_am_i():
    return {"user_id": current_user.user_id}
  1. The base URL where your authentication pages are hosted. You can find your Auth URL under the Backend Integration section for your project at https://app.propelauth.com.
  2. You can manage your api keys under the Backend Integration section for your project.

How it works

The front-end receives an access token. This access token is provided in an Authorization header when an HTTP request is made.

PropelAuth provides you with metadata that you use to validate the access token and figure out who it belongs to. The complexity of fetching the metadata and validating the tokens is hidden in the Flask library.

Installation

In your Flask app, install the propelauth_flask library.

$ pip install propelauth-flask

Initialize

init_auth performs a one-time initialization of the library. It will verify your api_key is correct and fetch the metadata needed to verify access tokens in require_user, optional_user, or require_org_member.

from propelauth_flask import init_auth

auth = init_auth("YOUR_AUTH_URL", #(1)
                 "YOUR_API_KEY") #(2)
  1. The base URL where your authentication pages are hosted. You can find this under the Backend Integration section for your project at https://app.propelauth.com.
  2. You can manage your api keys under the Backend Integration section for your project.

Protect API routes

require_user

A decorator that will verify the request was made by a valid user. Specifically, it will:

  1. Check that a valid access token was provided. If not, the request is rejected with a 401 status code.
  2. Set current_user (scoped to the current request) with the user's information.
from flask import Flask
from propelauth_flask import init_auth, current_user

app = Flask(__name__)
auth = init_auth("YOUR_AUTH_URL", "YOUR_API_KEY")

@app.route("/api/whoami")
@auth.require_user
def who_am_i():
    """This route is protected, current_user is always set"""
    return {"user_id": current_user.user_id} # (1)
  1. See current_user for more information

optional_user

Similar to require_user, except if an access token is missing or invalid, the request is allowed to continue, but current_user.exists() will be False.

from flask import Flask
from propelauth_flask import init_auth, current_user

app = Flask(__name__)
auth = init_auth("YOUR_AUTH_URL", "YOUR_API_KEY")

@app.route("/api/whoami_optional")
@auth.optional_user
def who_am_i_optional():
    if current_user.exists(): # (1)
        return {"user_id": current_user.user_id}
    return {}
  1. See current_user for more information

current_user

A per-request value that contains user information for the user making the request. It's set by one of require_user, optional_user, or require_org_member.

Property Description
user_id The id of the user
org_id_to_org_member_info A dictionary of org ids to metadata about the org. Includes all orgs that the user is in
exists() A function that returns True if the user is logged in and False otherwise. You only need to check this if you are using optional_user, otherwise it always returns True.

The values of org_id_to_org_member_info have these properties:

org_id_to_org_member_info properties Description
org_id The id of the org
org_name The name of the org
user_role The user's role within the org. See UserRole for more details.

require_org_member

A decorator that will verify the request was made by a valid user that belongs to a specific organization.

@app.route("/org/<org_id>/admin")
@auth.require_org_member(minimum_required_role=UserRole.Admin)
def hello(org_id):
   return f"You are an admin or owner of {current_org.org_name}"
# Expect users to query with /hello?org_id=...
def org_id_in_query_extractor(req):
   return req.args.get('org_id')

@app.route("/hello")
@auth.require_org_member(req_to_org_id=org_id_in_query_extractor)
def hello():
    return f"You are in {current_org.org_name}"
require_org_member Argument Description
req_to_org_id A function that takes in the request and outputs the org_id to require the user to be a member of. If none is specified, it will check for a path param org_id.
minimum_required_role If specified, require_org_member will check both that the user is a member of the organization, and that their role is >= minimum_required_role. If not, the request is rejected with a 403 Forbidden error.

Specifically, it will:

  1. Check that a valid access token was provided. If not, the request is rejected with a 401 status code.
  2. Set current_user (scoped to the current request) with the user's information.
  3. Find an id for an organization within the request. By default, it will check for a path parameter org_id.
  4. Check that the user is a member of that organization. If not, the request is rejected with a 403 status code.
  5. (Optionally) Check that the user's role in that organization is >= minimum_required_role. If not, the request is rejected with a 403 status code.
  6. Set current_org (scoped to the current request) with the organization's information for this user.

current_org

A per-request value that contains org information for the user making the request. It's set by require_org_member.

Property Description
org_id The id of the org
org_name The name of the org
user_role The user's role within the org. See UserRole for more details.

API calls

In addition to protecting API routes, you can make requests to PropelAuth to fetch more information about your users or organizations. You can also create new users, update user metadata, and more.

See Flask Library Reference for more information on available functionality.

Next Steps

Done with your backend? Next you can deploy to production.