FastAPI extension that provides JWT Auth support
Project description
fastapi-jwt-auth
Features
FastAPI extension that provides JWT Auth support (secure, easy to use and lightweight), if you were familiar with flask-jwt-extended this extension suitable for you because this extension inspired by flask-jwt-extended.
- Access token and refresh token
- Token freshness will only allow fresh tokens to access endpoint
- Token revoking/blacklisting
- Custom token revoking
Installation
pip install fastapi-jwt-auth
Usage
Setting AUTHJWT_SECRET_KEY
in environment variable
- For Linux, macOS, Windows Bash
export AUTHJWT_SECRET_KEY=secretkey
- For Windows PowerShell
$Env:AUTHJWT_SECRET_KEY = "secretkey"
Create it
- Create a file
basic.py
with:
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel, Field
from fastapi_jwt_auth import AuthJWT
app = FastAPI()
class User(BaseModel):
username: str = Field(...,min_length=1)
password: str = Field(...,min_length=1)
# Provide a method to create access tokens. The create_access_token()
# function is used to actually generate the token, and you can return
# it to the caller however you choose.
@app.post('/login',status_code=200)
def login(user: User):
if user.username != 'test' or user.password != 'test':
raise HTTPException(status_code=401,detail='Bad username or password')
# Identity can be any data that is json serializable
access_token = AuthJWT.create_access_token(identity=user.username)
return access_token
@app.get('/protected',status_code=200)
def protected(Authorize: AuthJWT = Depends()):
# Protect an endpoint with jwt_required, which requires a valid access token
# in the request to access.
Authorize.jwt_required()
# Access the identity of the current user with get_jwt_identity
current_user = Authorize.get_jwt_identity()
return {"logged_in_as": current_user}
Run it
Run the server with:
$ uvicorn basic:app --host 0.0.0.0 --port 5000
INFO: Started server process [6051]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
Access it
To access a jwt_required protected url, all we have to do is send in the JWT with the request. By default, this is done with an authorization header that looks like:
Authorization: Bearer <access_token>
We can see this in action using CURL:
$ curl http://localhost:5000/protected
{"detail":"Missing Authorization Header"}
$ curl -H "Content-Type: application/json" -X POST \
-d '{"username":"test","password":"test"}' http://localhost:5000/login
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTczMzMxMzMsIm5iZiI6MTU5NzMzMzEzMywianRpIjoiNDczY2ExM2ItOWI1My00NDczLWJjZTctMWZiOWMzNTlmZmI0IiwiZXhwIjoxNTk3MzM0MDMzLCJpZGVudGl0eSI6InRlc3QiLCJ0eXBlIjoiYWNjZXNzIiwiZnJlc2giOmZhbHNlfQ.42CusQo6nsLxOk6bBUP1vnVX-REx4ZYBYYIjYChWf0c"
$ export TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTczMzMxMzMsIm5iZiI6MTU5NzMzMzEzMywianRpIjoiNDczY2ExM2ItOWI1My00NDczLWJjZTctMWZiOWMzNTlmZmI0IiwiZXhwIjoxNTk3MzM0MDMzLCJpZGVudGl0eSI6InRlc3QiLCJ0eXBlIjoiYWNjZXNzIiwiZnJlc2giOmZhbHNlfQ.42CusQo6nsLxOk6bBUP1vnVX-REx4ZYBYYIjYChWf0c
$ curl -H "Authorization: Bearer $TOKEN" http://localhost:5000/protected
{"logged_in_as":"test"}
Extract Token
Access all URL to see what the result
from pydantic import BaseModel, Field
from fastapi import FastAPI, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT
app = FastAPI()
class User(BaseModel):
username: str = Field(...,min_length=1)
password: str = Field(...,min_length=1)
@app.post('/login',status_code=200)
def login(user: User):
if user.username != 'test' or user.password != 'test':
raise HTTPException(status_code=401,detail='Bad username or password')
access_token = AuthJWT.create_access_token(identity=user.username)
return access_token
# Returns the JTI (unique identifier) of an encoded JWT
@app.get('/get-jti',status_code=200)
def get_jti():
access_token = AuthJWT.create_access_token(identity='test')
return AuthJWT.get_jti(encoded_token=access_token)
# this will return the identity of the JWT that is accessing this endpoint.
# If no JWT is present, `None` is returned instead.
@app.get('/get-jwt-identity',status_code=200)
def get_jwt_identity(Authorize: AuthJWT = Depends()):
Authorize.jwt_optional()
current_user = Authorize.get_jwt_identity()
return {"logged_in_as": current_user}
# this will return the python dictionary which has all
# of the claims of the JWT that is accessing the endpoint.
# If no JWT is currently present, return None instead
@app.get('/get-raw-jwt',status_code=200)
def get_raw_jwt(Authorize: AuthJWT = Depends()):
Authorize.jwt_optional()
token = Authorize.get_raw_jwt()
return {"token": token}
Configuration Options
-
AUTHJWT_ACCESS_TOKEN_EXPIRES
How long an access token should live before it expires. If you not define in env variable default value is15 minutes
. Or you can custom with valueint
(seconds), exampleAUTHJWT_ACCESS_TOKEN_EXPIRES=300
its mean access token expired in 5 minute -
AUTHJWT_REFRESH_TOKEN_EXPIRES
How long a refresh token should live before it expires. If you not define in env variable default value is30 days
. Or you can custom with valueint
(seconds), exampleAUTHJWT_REFRESH_TOKEN_EXPIRES=86400
its mean refresh token expired in 1 day -
AUTHJWT_BLACKLIST_ENABLED
Enable/disable token revoking. Default value is None, for enable blacklist token:AUTHJWT_BLACKLIST_ENABLED=true
-
AUTHJWT_SECRET_KEY
The secret key needed for symmetric based signing algorithms, such as HS*. If this is not setraise RuntimeError
. -
AUTHJWT_ALGORITHM
Which algorithms are allowed to decode a JWT. Default value isHS256
Examples
Examples are available on examples folder. There are:
License
This project is licensed under the terms of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file fastapi_jwt_auth-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: fastapi_jwt_auth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2266b13b3109fc58dacd0d0d8e63bad8ab0d3fd382c591004508621b7485a95f |
|
MD5 | 4ddc11ff1345ada7d49202069d39078f |
|
BLAKE2b-256 | b6b16835b16de64669a08c36dc405d1fb411d86ff889f6c8e529b93d83b4566d |