Dependency Injection
Following the FastAPI dependency injection syntax, we can use the FastJWT dependencies in multiple places
Route
The straightforward usage is to protect a given route. Let's consider GET /protected
as the endpoint to protect.
Depending on your need for context you might want to use FastJWT dependencies as function or route dependencies.
If you don't need to know the user/recipient/subject context -e.g you need to display the same data to all your authenticated user regardless of who they are-
from fastapi import FastAPI
from fastapi import Depends
from fastjwt import FastJWT
app = FastAPI()
security = FastJWT()
@app.get('/protected', dependencies=[Depends(security.access_token_required)])
def protected(): # (1)!
...
- Used as a route dependency, it does not provide any context but only enforce authentication
If the recipient context is needed in the route logic, you can pass the dependency to the function to retrieve a TokenPayload
or a custom ORM object (see Custom Callbacks>User Serialization)
from fastapi import FastAPI
from fastapi import Depends
from fastjwt import FastJWT
from fastjwt import TokenPayload
app = FastAPI()
security = FastJWT()
@app.get('/protected')
def protected(payload: TokenPayload = Depends(security.access_token_required)): # (1)!
...
- Used as a function dependency, the return value is available as a function argument
Application
You can also apply dependencies at an application level. It might be useful if your application is not in charge of providing authentication token but only to protect routes.
from fastapi import FastAPI
from fastapi import Depends
from fastjwt import FastJWT
from fastjwt import TokenPayload
app = FastAPI(dependencies=[Depends(security.access_token_required)]) # (1)!
security = FastJWT()
@app.get('/protected')
def protected(payload: TokenPayload = Depends(security.access_token_required)): # (2)!
...
@app.get('/protected/nocontext')
def protected_no_context(): # (3)!
...
- Dependencies defined here will be applied to all the routes
- You still need to apply the dependency if you need to access the token context in your route
- The route is also protected but does not need context data
In the example above, all the application's routes require a valid access token. Note that in order to get the context in the route logic you'll have to specify the required dependency.
Note on performance
For routes where context is needed, it seems like the dependency is called 2 times. FastAPI creates a dependency graph and execute all the parent nodes from our selected dependency. FastAPI handles the runtime and does not execute the dependency multiple times.
APIRouter
Since adding global dependencies might be too narrow. We can use fastapi.APIRouter
to scope a selection of route to protect under a FastJWT dependency
from fastapi import APIRouter
from fastapi import Depends
from app import security
router = APIRouter(dependencies=[Depends(security.access_token_required)]) # (1)!
@router.get('/protected'):
def protected():
return "This is a protected endpoint"
- You can include the dependency in the APIRouter definition
from app import app
from app import security
from router import router
app.include_router(
router,
dependencies=[Depends(security.access_token_required)] # (1)!
)
- You can include the dependency in the APIRouter when including the router within the application instead of during router definition. This syntax is en EXCLUSIVE OR with regard to the one in
router.py