I'm working with FastAPI and Python on the backend to make external calls to a public API. After authentication, the public API gives an access token that grants access to a specific user's data. Where would be the best place to store/save this access token? I want to easily access it for all my future API calls with the public API service. I don't want a DB or long term storage as it only needs to last the session for the user. Appreciate all help!
-
2I would probably store this as an encrypted cookie on the request session. – flakes Jul 14 '22 at 05:28
-
@flakes So I would use a requests.Session to store the token and then would I need to pull that token out of the cookie everytime to pass it to the public API in a GET request for example? – oscar-lauth Jul 14 '22 at 05:54
-
Yeah, that would be how I do it. Make sure the cookie is secured with a secret by the server, such that the cookie can't be parsed by client-side code to call your APIs directly. – flakes Jul 14 '22 at 06:00
-
Thanks. Sorry, I'm pretty new to this stuff. Could that mean storing a secret in the FastAPI/backend py files and then using that secret to encode and decode the cookie stored in requests.Session? – oscar-lauth Jul 14 '22 at 06:03
-
2You shouldn't be storing secrets in the code, store them in environment variables which you set during deployment of the app. – Peter Henry Jul 14 '22 at 13:21
-
@PeterHenry gotcha I will store my secrets in env vars, but do you know of a better way to store the access token, like maybe in a User class field that I can access across files for different API requests? – oscar-lauth Jul 15 '22 at 03:07
-
@oscar-lauth, try some of the options here -> https://stackoverflow.com/questions/55212497/storing-oauth-token-in-python-library – Peter Henry Jul 15 '22 at 03:59
-
1@PeterHenry thanks, I ended up storing client secrets/id (which are permanent) in .env and then creating a global User class that gets initialized and stores the access token as well as some other data. – oscar-lauth Jul 17 '22 at 21:23
2 Answers
Almost a year later, but I found a clean solution I was pleased with. I used Starlette's SessionMiddleware to store the access_token and user session data in the backend.
Example:
from fastapi import Request
...
@router.get("/callback")
async def callback(request: Request):
...
request.session["access_token"] = access_token
Then later, in any endpoints where I need to use the token or get session data:
@router.get("/top_artists")
async def get_top_songs(request: Request):
...
access_token = request.session.get("access_token")
This stores access_token and any other session data you want on the backend. Then, a cookie, 'session_id', is stored client-side and passed through Request to retrieve the session data from the server.

- 85
- 9
When you receive an access token that is user-specific and doesn't need to be persisted across sessions, a good place to store it is in a user session. A user session is a place to store data that you want to persist across multiple requests but only for a specific user, and only for the duration of that user's interaction with your application.
FastAPI doesn't have built-in support for sessions as it's more low-level than some other web frameworks, but it can be easily combined with Starlette's SessionMiddleware.
Here's a simple example:
from starlette.middleware.sessions import SessionMiddleware
from fastapi import FastAPI, Depends
from starlette.requests import Request
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="your-secret-key")
@app.get("/set_token/")
async def set_token(request: Request):
request.session['token'] = 'your-token'
return {"message": "Token set"}
@app.get("/get_token/")
async def get_token(request: Request):
return {"token": request.session.get('token')}
In the above code, we're adding a SessionMiddleware to our FastAPI app, which allows us to use request.session as a dictionary where we can store user-specific data. We then define two routes, one to store a token in the session, and another to retrieve it.
In your case, after a user authenticates and you get an access token from the public API, you would store it in request.session['token']. Then, whenever you need to make an API call for that user, you can retrieve the token from request.session['token'].
This keeps the token tied to the specific user's session and doesn't involve any databases or long-term storage. Note that the session data is signed but not encrypted, meaning that users could read the contents, but not modify them. Therefore, it's important not to store sensitive data in sessions. If your tokens are sensitive, you should use a more secure method to store them.
Finally, remember to replace "your-secret-key" with a secure, randomly generated string. This key is used to sign the session data to prevent tampering.
Also note, this example is extremely simplistic. You'll probably want more robust error handling and checks in a real-world application. For example, before retrieving the token, you should check if it exists in the session and handle the case if it doesn't.

- 11
- 2