Skip to main content

FastAPI-Login

FastAPI-Login tries to provide similar functionality as Flask-Login does.

Documentation

In-depth documentation can but found at fastapi-login.readthedocs.io Some examples can be found here

Installation

$ pip install fastapi-login

Usage

To begin we have to setup our FastAPI app:

from fastapi import FastAPI

SECRET = 'your-secret-key'

app = FastAPI()

To obtain a suitable secret key you can run import os; print(os.urandom(24).hex()).

Now we can import and setup the LoginManager, which will handle the process of encoding and decoding our Json Web Tokens.

from fastapi_login import LoginManager

manager = LoginManager(SECRET, token_url='/auth/token')

For the example we will use a dictionary to represent our user database. In your application this could also be a real database like sqlite or Postgres. It does not matter as you have to provide the function which retrieves the user.

fake_db = {'johndoe@e.mail': {'password': 'hunter2'}}

Now we have to provide the LoginManager with a way to load our user. The user_loader callback should either return your user object or None

@manager.user_loader()
def load_user(email: str):  # could also be an asynchronous function
    user = fake_db.get(email)
    return user

Now we have to define a way to let the user login in our app. Therefore we will create a new route:

from fastapi import Depends
from fastapi.security import OAuth2PasswordRequestForm
from fastapi_login.exceptions import InvalidCredentialsException

# the python-multipart package is required to use the OAuth2PasswordRequestForm
@app.post('/auth/token')
def login(data: OAuth2PasswordRequestForm = Depends()):
    email = data.username
    password = data.password

    user = load_user(email)  # we are using the same function to retrieve the user
    if not user:
        raise InvalidCredentialsException  # you can also use your own HTTPException
    elif password != user['password']:
        raise InvalidCredentialsException
    
    access_token = manager.create_access_token(
        data=dict(sub=email)
    )
    return {'access_token': access_token, 'token_type': 'bearer'}

Now whenever you want your user to be logged in to use a route, you can simply use your LoginManager instance as a dependency.

@app.get('/protected')
def protected_route(user=Depends(manager)):
    ...

If you also want to handle a not authenticated error, you can add your own subclass of Exception to the LoginManager.

from starlette.responses import RedirectResponse

class NotAuthenticatedException(Exception):
    pass

# these two argument are mandatory
def exc_handler(request, exc):
    return RedirectResponse(url='/login')

# This will be deprecated in the future
# set your exception when initiating the instance
# manager = LoginManager(..., custom_exception=NotAuthenticatedException)
manager.not_authenticated_exception = NotAuthenticatedException
# You also have to add an exception handler to your app instance
app.add_exception_handler(NotAuthenticatedException, exc_handler)

To change the expiration date of the token use the expires_delta argument of the create_access_token method with a timedelta. The default is set 15 min. Please be aware that setting a long expiry date is not considered a good practice as it would allow an attacker with the token to use your application as long as he wants.

from datetime import timedelta

data = dict(sub=user.email)

# expires after 15 min
token = manager.create_access_token(
    data=data
)
# expires after 12 hours
long_token = manager.create_access_token(
    data=data, expires=timedelta(hours=12)
)

Usage with cookies

Instead of checking the header for the token. fastapi-login also support access using cookies.

from fastapi_login import LoginManager

manager = LoginManager(SECRET, token_url='/auth/token', use_cookie=True)

Now the manager will check the requests cookies the headers for the access token. The name of the cookie can be set using manager.cookie_name. If you only want to check the requests cookies you can turn the headers off using the use_header argument

For convenience the LoginManager also includes the set_cookie method which sets the cookie to your response, with the recommended HTTPOnly flag and the manager.cookie_name as the key.

from fastapi import Depends
from starlette.responses import Response


@app.get('/auth')
def auth(response: Response, user=Depends(manager)):
    token = manager.create_access_token(
        data=dict(sub=user.email)
    )
    manager.set_cookie(response, token)
    return response
    

Release files for fastapi-login 1.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastapi-login 1.8.0
File Size Uploaded
fastapi-login-1.8.0.tar.gz 15.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastapi-login 1.8.0
File Interpreter ABI Platform
fastapi_login-1.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 33.3 kB

Release files / fastapi-login-1.8.0.tar.gz

Download URL fastapi-login-1.8.0.tar.gz
Size 15.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d1745093bc9e7167f0c35478177f5c8bfc85191161ca257aa2e0483d8f398f17
BLAKE2b-256 checksum
How to use checksums
88193b79a09b8ddf6ff3686f1ad86c21f2949175f045a79867fce8d8527b78ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.2

Release files / fastapi_login-1.8.0-py3-none-any.whl

Download URL fastapi_login-1.8.0-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3977fae79d20568f580b59017d9073e0d6f933c821fe9596d04f16a2ab67605b
BLAKE2b-256 checksum
How to use checksums
e07390601ce2f8e5b02d3f530904dbb0ac22558e7ac5fd6c6e1d16fdc17aef93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.2

Release history Release notifications | RSS feed

1.10.3

2 release files

1.10.2

2 release files

1.10.1

2 release files

1.9.3

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

This release

1.8.0 This release

2 release files

1.7.3

2 release files

1.7.2

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.3

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.4

1 release file

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page