This article explains enhancing token validation for user login in FastAPI, ensuring valid tokens and correct user information.
This article explains how to enhance the token validation process for a login user route in FastAPI. We not only ensure that a valid token is received but also confirm that it carries the correct user information. The sections below provide detailed explanations of the logic and code samples that demonstrate how to implement these features.
In this section, we first test the user creation flow by verifying that the response returns the correct email and status code. Then, we test the login route by performing a POST request with the user’s credentials and ensuring that a valid token is generated.
Within the authentication router (typically found in your auth.py under the routers directory), the login endpoint uses a Token schema as its response model. The code snippet below shows the login route that confirms the user’s existence and validates the provided password:
Copy
Ask AI
@router.post('/login', response_model=schemas.Token)def login(user_credentials: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(database.get_db)): user = db.query(models.User).filter(models.User.email == user_credentials.username).first() if not user: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Invalid Credentials" ) if not utils.verify(user_credentials.password, user.password): raise HTTPException
After testing this endpoint, you may observe similar warnings together with confirmation output:
Copy
Ask AI
venv\lib\site-packages\aiofiles\os.py:10venv\lib\site-packages\aiofiles\os.py:10c:\users\sanje\documents\courses\fastapi\venv\lib\site-packages\aiofiles\os.py:10: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead============================= test session starts ==============================platform win32 -- Python 3.9.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1collected 2 itemstests/test_calculations.py .. [100%]============================== 2 passed, 5 warnings in 1.53s ===============================
For user creation testing, the schemas module provides access to the necessary token schema. The following code snippet demonstrates the user creation test:
Copy
Ask AI
def test_create_user(client): res = client.post( "/users/", json={"email": "[email protected]", "password": "password123"} ) new_user = schemas.UserOut(**res.json()) assert new_user.email == "[email protected]" assert res.status_code == 201def test_login_user(test_user, client): # Login test will be defined below.
Once the access token is received, decoding it is crucial to verify that it contains the correct user information. The logic used is similar to what is implemented in the OAuth2.py file for retrieving the current user. The get_current_user function decodes the token and uses the embedded user_id to fetch the corresponding user from the database:
The verify_access_token function leverages the jwt.decode method to validate the token and extract the user’s ID. If the token is invalid, it immediately raises an exception:
Copy
Ask AI
def verify_access_token(token: str, credentials_exception): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) id: str = payload.get("user_id") if id is None: raise credentials_exception token_data = schemas.TokenData(id=id) except JWTError: raise credentials_exception return token_data
After obtaining the token from the login response, decode it using your application settings (imported from your configuration module). This allows you to extract and validate the user_id. The final login test confirms that the decoded token contains the correct user details and that the token type is set to “bearer”.
Ensure that the configuration from, for example, app.config import settings is properly imported so that the secret_key and algorithm values are correctly referenced during the token decoding process.
The test fixture used to create a test user is vital for ensuring consistent test results. Ensure that the test user creation code is correctly configured.
Below is an example of a test fixture for creating a test user:
When running the tests, you might see deprecation warnings from the aiofiles module:
Copy
Ask AI
venv\lib\site-packages\aiofiles\os.py:10venv\lib\site-packages\aiofiles\os.py:10c:\users\sanje\documents\courses\fastapi\venv\lib\site-packages\aiofiles\os.py:10: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead-- Docs: https://docs.pytest.org/en/stable/warnings.html2 passed, 5 warnings in 1.53s
The final login user test confirms that the token correctly decodes to the expected user details and that the token type is set to “bearer”. This robust validation ensures that both the login process and token authentication work seamlessly in your FastAPI application.