Token-Based Authentication – A Beginner-Friendly Walkthrough


Having worked on token-based authentication for over two years and successfully deploying both single-server and distributed web apps in production, I thought of writing down the exact steps I followed—and all the mistakes I made along the way.
Authentication and authorization are among the most important concepts to understand if you’re trying to become a backend engineer or even a full stack developer. They enable security, scalability and single sign-on across applications in an organization.
Authentication vs Authorization
Authentication: Confirming who you are (logging in).
Authorization: Deciding what you are allowed to do after you’ve logged in.
Note: I’m not going to talk here about attacks and security threats (that’s for another post). This is purely about integrating token-based authentication.
Understanding the User Flow
My genuine attempt here is to explain the flow in the simplest way possible, without getting lost in jargon. Later we’ll get into the terms like OAuth, OIDC, and JWT—but first, let’s just see how it works step by step:
The user opens an app (for example, a reporting dashboard).
The app redirects the browser to an Identity Provider / Authorization Server (a service that already knows the app and the user).
The user enters their credentials (username, password, MFA if enabled).
The IdP validates the user and issues tokens – usually:
ID Token (JWT): proves who the user is.
Optionally, Access Token: gives the app controlled access to APIs or resources.
The tokens carry user details (id, email, roles, access rights, expiry times, etc.).
The client stores these tokens (in memory or a session).
Every subsequent request includes the token(s) so the user doesn’t need to log in again until the tokens expire.
What is OpenID Connect (OIDC) and why does it sit on top of OAuth?
OAuth 2.0 is an authorization protocol.
It defines how a client application can obtain a time-limited access token from an Authorization Server (commonly provided by an Identity Provider such as Google, Okta, or an internal enterprise IdP).
The client then presents this token to an API (Resource Server) to gain controlled access to protected resources on behalf of the user.
Importantly, OAuth itself does not define how the user is authenticated — it only handles the delegation of access after authentication has already happened.
OpenID Connect (OIDC) is an authentication layer built on top of OAuth 2.0.
It standardizes how a client application can verify the identity of an end-user based on the authentication performed by an Authorization Server, and obtain basic profile information about the user in a structured, signed format.
In addition to issuing an access token (for resource access), the server also issues an ID token (a JWT) that contains identity claims such as sub (user ID), email, and name.
Keywords in This Flow
Resource Owner: The user (you).
Client / Relying Party: The application you are trying to use (e.g., your internal dashboard).
Resource Server / API: The backend service that holds the data or functionality you want to access.
These servers may optionally require an Access Token from the client app to allow access.An Identity Provider (IdP) is a service that:
Authenticates users (checks who you are)
Issues tokens (JWTs, access tokens)
Optionally acts as an Authorization Server when OAuth 2.0 is used
Examples:
Internal company login system (e.g., Okta, Active Directory Federation)
Public providers like Google, Microsoft, GitHub
A JWT (JSON Web Token) is a compact, URL-safe way of representing information between two parties.
It’s just a string that looks like this:CopyEditeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0IiwibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huQGRvZS5jb20ifQ. TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
When decoded, it has three parts:
Header – metadata about the token (e.g., algorithm).
Payload – claims (user ID, email, roles, expiry time, etc.).
Signature – ensures the token hasn’t been tampered with.
The server signs the token, and every request carrying this token can be quickly verified by the application without re-checking the database each time.
Now that we understand the basics, here’s the high-level login flow:
The user is redirected to an Authorization Server/Identity Provider, logs in, and the app exchanges a temporary code for tokens (ID Token for authentication and Access Token for authorization).
Two common patterns:
Authorization Code Flow (shown in the diagram below): More secure; tokens are issued after exchanging an authorization code on the server side.
Implicit Flow: Tokens are returned directly in the browser without a code exchange, but this is less secure and mostly legacy.
What’s Next?
In Part 2, I’ll cover:
How tokens are stored and validated
Authorization Code Flow vs Implicit Flow and how to test before writing code
Common practices for single-server vs distributed environments
How to safely handle token expiration and refresh.
Subscribe to my newsletter
Read articles from Krupa Sawant directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
