How Authentication Actually Works

Authentication is a cornerstone of contemporary applications. Virtually every app demands user login, identity verification, and secure sessions. Though it's ubiquitous, many developers implement authentication without a complete understanding of it's inner workings.

This article breaks down authentication step-by-step, explaining the core concepts used in most web applications today.


Authentication vs Authorization

Before diving into implementation, it's important to understand the difference between authentication and authorization.

Authentication answers the question:

Who are you?


Authorization answers the question:

What are you allowed to do?


For example:
- Logging into an account is authentication
- Accessing an admin dashboard is authorization

Most systems perform authentication first, then determine permissions.


The Basic Login Flow

A typical authentication process looks like this:

1. User enters email and password.
2. Server verifies the credentials.
3. Server creates a session or token.
4. Client stores that session/token.
5. Client sends it with future requests.
6. Server verifies the session/token each time.

This process allows the server to recognize a user without requiring them to log in repeatedly.


Password Storage (The Right Way)

One of the biggest mistakes beginners make is storing passwords as plain text, which is extremely dangerous.

Instead passwords should always be hashed before being stored. Hash functions are generally not reversable, and can only be compared.

Example:

password123
  ↓
$2a$12$5OmnL63fGHCYbApIDqsXWOlF/Gm6QKkr0TfCqq58m0I1k3.7eXxYO

Even if someone gains access to the database, they cannot easily recover the original passwords.

Modern applications use specialized password hashing algorithms such as:

  • bcrypt
  • argon2
  • scrypt

These algorithms are intentionally slow, making brute-force attacks far more difficult.


Adding Salt to Passwords

Password hashing alone is not enough. Attackers often use rainbow tables, which are pre-computed databases of common passwords and their hashes.

To prevent this, systems add a salt to each password. A salt is a random value combined with the password before hashing.

Example:

password123 + random_salt
  ↓
hashed_result

Because every user has a unique salt, identical passwords produce different hashes.


Sessions

One of the most common authentication methods is session-based authentication.

Here's how it works.

Step 1: User logs in

The user sends credentials to the server.

POST /login
email: [email protected]
password: password123

Step 2: Server verifies credentials

The server compares the hashed password with the stored hash.

If valid, the server creates a session.

Step 3: Session ID is generated

The server generates a random session ID.

Example:

session_id = "abc12342069"

Step 4: Session is stored on the server

The server stores something like:

session_id → user_id

Step 5: Session ID is sent to the browser

Usually via a cookie.

Set-Cookie: session_id=abc12342069
GET /dashboard
Cookie: session_id=abc12342069

Step 7: Server checks the session

The server looks up the sessions, verifies that it is not expired, and identifies the user.

This allows the server to maintain state between requests.


JSON Web Tokens (JWT)

Another popular authentication approach uses JSON Web Tokens.

Instead of storing session data on the server, authentication data is stored inside a signed token.

Example token payload:

{
  "user_id": 42,
  "email": "[email protected]",
  "exp": 1000198980
}

This token would be signed with a secret key. When the client sends the token, the server verifies the signature to confirm it hasn't been altered.

Example request:

Authorization: Bearer uyJhbGcZTiJIUzI1...

If the signature is valid, the server trusts the data inside the token.


Sessions vs JWTs

Both approachs are widely used.

Sessions

Pros:

  • Easy to invalidate
  • Simple security model
  • Small cookies

Cons:

  • Requires server storage
  • Harder to scale across multiple servers

JWT

Pros:

  • Stateless
  • Works well with distributed systems
  • No session database required

Cons:

  • Harder to revoke
  • Larger request size
  • Security mistakes are common

Because of the tradeoffs, many large systems still use session-based authentication.


Refresh Tokens

JWTs often include an expiration time.

Example:

"exp": 1000198980

Once expired, the user must authenticate again, to improve user experience systems use refresh tokens.

The flow looks like this:

1. User logs in
2. Server issues:
- Access token (short-lived)
- Refresh token (long-lived)
3. Acess token expires
4. Client sends refresh token
5. Server issues a new access token

This allows sessions to remain active without requiring the user to log in repeatedly.


OAuth (Login With Google)

OAuth allows users to authenticate using third-party services.
Examples include:

  • Login with Google
  • Login with GitHub
  • Login with Apple

The flow works like this:

1. User clicks "Login with Google"
2. Browser redirects to Google
3. User approves access
4. Google sends an authorization code
5. Your server exchanges the code for a token
6. Server retrieves user information

This allows your application to authenticate users without managing their passwords.


Modern Authentication: Passkeys

Passwords are slowly being replaced by passkeys.

Passkeys use public-key cryptography instead of passwords. The process works like this:

1. Device generates a public/private key pair (typically RSA)
2. Public key is stored by the server
3. Private key remains on the device
4. Login requires biometric verification or device unlock
5. Device signs a challenge from the server

Because the private key never leaves the device, phishing attacks become much harder.

Passkeys are supported by most major platforms today.


Common Authentication Mistakes

Even experienced developers make authentication mistakes

Some common problems include

Storing plain text passwords

Never store plain text passwords, always use a secure hashing algorithm or some kind of encryption. Although hashing is preferred.

Weak session tokens

Session IDs must be cryptographically random. Predictable tokens allow attacks to hijack accounts.

Missing HTTPS

Authentication tokens should never be transmitted over HTTP. Always use HTTPS.

Long Lived Tokens

Tokens that never expire increase the risk of account compromise. Short lifetimes reduce damage if tokens are stolen.

Improper token storage

JWTs stored in localStorage are vulnerable to XSS attacks. Secure HTTP-only cookies are generally faster


Final Thoughts

Authentication systems can appear simple at first, but the underlying mechanisms involve many subtle security considerations.

A robust authentication system usually includes:

  • Secure password hashing
  • Session or token management
  • Expiration and renewal stategies
  • HTTPS enforcement
  • Proper storage of credentials

Understanding how these pieces work together allows developers to build secure applications and avoid common vulnerabilities.

As applications grow and security expectations increase, authentication will continue evolving with technologies like passkeys and hardware-backed credentials. But the core principles remain the same:

verify identity, protect credentials, and securely maintain user sessions