What We’ll Build
JWT Tokens
Cryptographically signed tokens that can’t be forged
Password Hashing
Secure password storage with industry-standard algorithms
Token Expiration
Tokens that automatically expire after a set time
Secure Validation
Proper token validation and user authentication
Installing Dependencies
We’ll use two additional packages:- PyJWT: For creating and validating JWT tokens
- pwdlib: Modern password hashing library (supports Argon2, bcrypt, scrypt)
Argon2 is the current winner of the Password Hashing Competition and is recommended for new applications.
Configuration and Setup
First, let’s set up our security configuration:Password Hashing
Let’s create functions to hash and verify passwords:Database Models
In production, replace
fake_users_db with a real database using SQLAlchemy, MongoDB, or your preferred database.JWT Token Creation
Now let’s create JWT tokens:JWT Token Structure
A JWT token contains three parts (separated by dots):sub(subject): The usernameexp(expiration): Unix timestamp when the token expires- The signature ensures the token hasn’t been tampered with
User Authentication
Create functions to get and authenticate users:Get Current User (with JWT)
Now let’s implement proper token validation:1
Extract the token
oauth2_scheme extracts the JWT from the Authorization header2
Decode and verify
jwt.decode() verifies the signature and expiration, then decodes the payload3
Extract username
Get the username from the
sub (subject) claim4
Get user from database
Look up the user in the database
5
Return user
Return the validated user object
Login Endpoint
Finally, create the login endpoint that issues JWT tokens:Protected Endpoints
Now you can protect any endpoint:Complete Working Example
Click to see full code
Click to see full code
Testing the Authentication
1
Get a token
2
Use the token
3
Wait for expiration
After 30 minutes, the token will expire and you’ll get a 401 error
Security Best Practices
Secret Key
- Generate with
openssl rand -hex 32 - Store in environment variables
- Use different keys per environment
Token Expiration
- Short expiration (15-30 minutes)
- Implement refresh tokens for longer sessions
- Force re-authentication for sensitive actions
Password Hashing
- Use Argon2id or bcrypt
- Never store plain text passwords
- Use timing-safe comparisons
HTTPS Only
- Always use HTTPS in production
- Tokens sent over HTTP can be intercepted
- Use secure cookies when applicable
Generating Password Hashes
To create a new user, hash their password:Next Steps
Now let’s add fine-grained permissions with OAuth2 scopes:OAuth2 Scopes
Learn how to implement OAuth2 scopes for role-based access control