Added the local endpoint

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-07 09:49:33 +01:00
parent eaa1fbf0ac
commit 33b681bace
5 changed files with 91 additions and 13 deletions

View file

@ -62,6 +62,49 @@ To run tests, run the following command from the root of the project directory:
pytest
```
## Local Development
During local development, you may need to generate and use a dummy JWT to
test protected endpoints of the application.
# Generating a Dummy JWT
FastAPI provides a convenient way to generate a dummy JWT for testing.
To generate a dummy JWT, follow the steps below:
Make sure your application is running in a local environment.
The dummy token endpoint is only available in a local environment.
While your application is running, visit the /dummy-token endpoint using a tool
like curl or any HTTP client like Postman.
For instance, if your server is running locally on port 8000, you can use curl
to get a dummy token:
```commandline
curl http://localhost:8000/dummy-token
```
You will receive a response containing the dummy JWT
```json
{
"dummy_token": "<Your Dummy Token>"
}
```
### Using the Dummy JWT
Once you've obtained a dummy JWT, you can use it to make requests to
protected endpoints in your application:
1. When making a request, include an Authorization header with the value Bearer
<Your Dummy Token>. Replace <Your Dummy Token> with the token you
received from the /dummy-token endpoint.
2. Now you can make requests to the protected endpoints of the application.
Remember, the dummy JWT is meant for testing purposes only and should not be
used in production environments. The /dummy-token endpoint is not available
in non-local environments.
### Thoughts for authenticating the frontend with the backend
To provide secure communication between your frontend Next.js application and your backend FastAPI service, you have several options. Here are a few popular approaches:

View file

@ -19,11 +19,14 @@ async def validate_api_key(api_key_header: str = Depends(api_key_header)):
def get_user(user_id: str):
# Define here how to fetch a user from your database
# using the user_id. Here's a simple placeholder implementation:
# TODO: This is a placeholder implementation that needs to be fully tested with the front end
user = None
if user_id == "known_id":
user = {"id": user_id, "name": "Known User"}
return user
# TODO: Update this function to fetch a user from your actual database
if get_settings().ENVIRONMENT == "local":
return {"id": user_id, "name": "Dummy User"}
else:
user = None
if user_id == "known_id":
user = {"id": user_id, "name": "Known User"}
return user
def validate_jwt_token(token: str = Depends(oauth2_scheme)):
@ -33,8 +36,7 @@ def validate_jwt_token(token: str = Depends(oauth2_scheme)):
headers={"WWW-Authenticate": "Bearer"},
)
try:
# TODO: This is a placeholder implementation that needs to be fully tested with the front end
# the SECRET_KEY should match the NEXTAUTH_SECRET in the front end
# The SECRET_KEY should match the NEXTAUTH_SECRET in the front end
payload = jwt.decode(token, get_settings().SECRET_KEY, algorithms=[get_settings().ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
@ -48,10 +50,10 @@ def validate_jwt_token(token: str = Depends(oauth2_scheme)):
async def validate_token(token: str = Depends(oauth2_scheme)):
if get_settings().ENVIRONMENT != "local":
token_data = validate_jwt_token(token)
if not token_data:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials"
)
token_data = validate_jwt_token(token)
if not token_data:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials"
)
return token

View file

View file

@ -0,0 +1,28 @@
from fastapi import APIRouter, HTTPException, status, Depends
from jose import jwt
import datetime
from app.config import get_settings
router = APIRouter(
prefix="/local",
tags=["local"],
)
def create_dummy_token(secret: str, algorithm: str):
data = {
"sub": "known_id",
"name": "Test User",
"iat": datetime.datetime.utcnow(),
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
}
return jwt.encode(data, secret, algorithm=algorithm)
@router.get("/dummy-token")
async def dummy_token():
settings = get_settings()
if settings.ENVIRONMENT != "local":
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
detail="Dummy token can only be generated in local environment")
return {"dummy_token": create_dummy_token(settings.SECRET_KEY, settings.ALGORITHM)}

View file

@ -1,9 +1,14 @@
from fastapi import FastAPI, Depends
from app.portfolio import router as portfolio_router
from app.dependencies import validate_api_key, validate_token
from app.config import get_settings
app = FastAPI(dependencies=[Depends(validate_api_key), Depends(validate_token)])
app.include_router(portfolio_router.router)
if get_settings().ENVIRONMENT == "local":
from app.local import router as local_router
app.include_router(local_router.router)