Access Tokens vs Refresh Tokens
Introduction
While implementing authentication in a backend project, I realized that many things that sound simple on paper become surprisingly detailed in practice. Two of those were token-based authentication and email verification.
This blog documents what I learned while working with:
- Access tokens and refresh tokens
- User verification emails using MongoDB Atlas and Mailtrap
The goal here is clarity: both for understanding now and for remembering how everything fits together later.
Access Tokens (short-lived authorization)
An access token is used to prove that a user is authenticated when accessing protected resources.
Important characteristics:
- Short expiry time (minutes)
- Sent with each protected API request
- Commonly implemented using JWT
Purpose:
- Fast authorization checks
- Reduced damage if the token is compromised
Mental model: an access token answers the question
“Is this user allowed to do this right now?”
Refresh Tokens (session continuity)
A refresh token is used to obtain a new access token after the old one expires, without asking the user to log in again.
Important characteristics:
- Long-lived compared to access tokens
- Stored securely (often server-side or in HTTP-only cookies)
- Never sent with normal API requests
Purpose:
- Maintain user sessions
- Improve user experience without sacrificing security
Mental model: a refresh token answers the question
“Can this user be trusted to receive a new access token?”
Why access and refresh tokens are separated
Using only one token creates trade-offs:
- Long-lived tokens → security risk
- Short-lived tokens only → poor user experience
Separating responsibilities:
- Access token → authorization
- Refresh token → session management
This separation allows:
- Token rotation
- Easier revocation
- Better control over session lifetime
User verification email: the full flow
What looks like a single action is actually a multi-step process.
Step 1: User creation (unverified state)
On sign-up:
- User data is stored in MongoDB Atlas
- Password is hashed
- User is marked as unverified
This ensures access is limited until verification is complete.
Step 2: Verification token generation
A verification token must:
- Be unique and hard to guess
- Have a defined expiry time
- Be linked to a specific user
The token and its metadata are stored in the database so they can be validated later.
Step 3: Sending the email (Mailtrap)
Mailtrap is used to safely test email delivery during development.
Backend responsibilities:
- Configure SMTP transport
- Construct a verification link containing the token
- Send an email with clear instructions
- Handle failures (email not sent, retry logic)
Even with a testing service, this step requires careful handling.
Step 4: Token verification
When the user clicks the verification link:
- Token is extracted from the request
- Backend checks if the token exists
- Expiry time is validated
- Token usage is checked
- User account is marked as verified
This step ensures that only valid and intended users are activated.
Key takeaways
- Access tokens and refresh tokens serve different roles
- Token expiration is a security feature, not an inconvenience
- Email verification is a controlled workflow, not a single action
- Databases and email services must work together cleanly
Understanding the flow end-to-end makes authentication logic easier to reason about.
Conclusion
Implementing authentication highlighted how much planning goes into even basic user flows. Token design, database structure, and email handling all contribute to a secure system.
This experience helped solidify how modern authentication works beyond just the theory and reinforced the importance of designing flows, not just endpoints.