Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use refresh token with fastapi?

I'm trying to find an example of using the refresh token in fastapi. The fastapi docs provides an example of how to create a bearer token with a limited lifetime but not how to refresh the token.

For flask there is flask-jwt-extended but didn't find something similar for fastapi.

Any suggestions will be appreciated thx!

like image 915
kederrac Avatar asked Jun 16 '20 16:06

kederrac


People also ask

How do I trigger a refresh token?

To use the refresh token, make a POST request to the service's token endpoint with grant_type=refresh_token , and include the refresh token as well as the client credentials if required.

How do I use JWT in FastAPI?

Handle JWT tokens Create a variable ALGORITHM with the algorithm used to sign the JWT token and set it to "HS256" . Create a variable for the expiration of the token. Define a Pydantic Model that will be used in the token endpoint for the response. Create a utility function to generate a new access token.

How should refresh tokens be used?

The main purpose of using a refresh token is to considerably shorten the life of an access token. The refresh token can then later be used to authenticate the user as and when required by the application without running into problems such as cookies being blocked, etc.

How to authenticate with the fastapi API?

So, to authenticate with our API, it sends a header Authorization with a value of Bearer plus the token. If the token contains foobar, the content of the Authorization header would be: Bearer foobar. FastAPI provides several tools, at different levels of abstraction, to implement these security features.

Is there a flask-JWT-extended for fastapi?

The fastapi docs provides an example of how to create a bearer token with a limited lifetime but not how to refresh the token. For flask there is flask-jwt-extended but didn't find something similar for fastapi. Any suggestions will be appreciated thx! You might wanna check out fastapi-jwt-auth. It is inspired by flask-jwt-extended.

How does fastapi read a JWT token?

In the simplest case, someone else takes care of acquiring a valid JWT token so that FastAPI then can simply decode and read the user and permissions.

Is refresh token a good fit for this library?

I think refresh token is a requirement for most projects once they get off the ground, and it seems like a perfect fit to add to this library. For my part, I'm actually going to switch off fastapi-users to fastapi-jwt-auth since it handles refresh tokens.


1 Answers

You might wanna check out fastapi-jwt-auth. It is inspired by flask-jwt-extended. There is a good documentation on how to use the refresh token with good examples.

First you need to install the package: pip install fastapi-jwt-auth. And configure the secret. Then on the login create a refresh token and access token and return it to the user.


from fastapi import FastAPI, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    email: str
    password: str

class Settings(BaseModel):
    authjwt_secret_key: str = "secret"

@AuthJWT.load_config
def get_config():
    return Settings()

@app.post('/login')
def login(user: User, Authorize: AuthJWT = Depends()):
    if user.email != "[email protected]" or user.password != "test":
        raise HTTPException(status_code=401,detail="Incorrect email or password")
    access_token = Authorize.create_access_token(subject=user.email)
    refresh_token = Authorize.create_refresh_token(subject=user.email)
    return {"access_token": access_token, "refresh_token": refresh_token}

In the next step you should create an Endpoint to refresh the access token.

@app.post('/refresh')
def refresh(Authorize: AuthJWT = Depends()):
    Authorize.jwt_refresh_token_required()
    current_user = Authorize.get_jwt_subject()
    new_access_token = Authorize.create_access_token(subject=current_user)
    return {"access_token": new_access_token}

# Example protected Endpoint
@app.get('/hello')
def refresh(Authorize: AuthJWT = Depends()):
    Authorize.jwt_required()
    return {"hello": "world"}

Note this only a small example from a security perspective you should swap the refresh tokens on refresh and blacklist the old token. The library offers therefore the decorator @AuthJWT.token_in_denylist_loader. You could implement the blacklist with an in-memory database that keeps invalidated tokens until the expiry date is reached. Also in production choose a real secret.

like image 91
metro2012 Avatar answered Sep 20 '22 11:09

metro2012