There was a time I called JWT an “authentication method,” said I logged in “with OAuth,” and lumped SSO and SAML together as the same thing. Since the terms all sit around authentication, they kept blurring in my head. I wanted to line them up once and for all.

Two questions anchor the lineup. One: how do you prove “who you are”? The other: how do you carry that proof across stateless HTTP requests?

Authentication vs Authorization

These two get confused most often.

Authentication answers “who are you” — it verifies that the identity a user claims is genuine. Authorization answers “what are you allowed to do” — it decides whether a verified identity has permission for a given resource or action.

There is an order. Authentication comes first, authorization second. Logging in is authentication; whether that user can enter the admin page is authorization. Calling JWT “authentication” and calling OAuth “login” both come from blurring this distinction.

Basic · Digest · API Key

The simplest starting point is to put the credentials themselves into the request.

Basic authentication Base64-encodes id:password and puts it in the Authorization header. Base64 is encoding, not encryption. Anyone can decode and read it, so HTTPS is a precondition. It shows up less in human-facing login services and more in server-to-server communication and internal tooling.

Digest authentication emerged to avoid that Base64 exposure. The server issues a nonce, and the client sends a hash computed from the nonce, the password, and request details, so the plaintext password never travels the network. It was originally MD5-based and later gained SHA-256 (RFC 7616), but it has largely been displaced by the token-plus-TLS combination.

API Key issues a random string per client, sent in a header (X-API-KEY and the like) with each request. The server looks the key up in a store to confirm whose key it is and what permissions it carries. It fits third-party integrations and script-based calls well. The catch is that the key has no built-in expiry — once leaked, it stays valid until you revoke or rotate it by hand. And since it’s an unstructured string, every request needs a lookup.

These methods share one trait: they resend the proof on every request. Keeping no state makes them simple, but it falls short for a web service where a person logs in and stays for a while. That’s where carrying a one-time proof forward comes in.

Session and Token

You log in once, but the requests keep coming. You can’t send the password every time, so you store the fact that “this user is already verified” somewhere, and later requests carry only the token for it. Where you store it is the fork in the road.

A session keeps the state on the server. On login, the server creates a session and hands back only a session ID via cookie. Because the server controls it directly, immediate invalidation — forced logout, for instance — is easy; the trade-off is that the server has to remember state, so horizontal scaling needs a shared store.

A token (JWT, JSON Web Token) puts the information inside the token itself and entrusts it to the client. The server only verifies the signature, holds no state, and scales freely across distributed environments. The trade-off is that an issued token is hard to invalidate before it expires.

The internal structure of the two, storage strategies, and the access-token / refresh-token split are a deeper topic, left aside here.

OAuth 2.0 and OpenID Connect

From here on, your server isn’t authenticating directly — it’s borrowing someone else’s identity provider. And this is the pair that gets mixed up the most.

OAuth 2.0 (Open Authorization) is an authorization framework, not authentication. Its purpose is delegation. Without handing their password to a third-party app, a user delegates permission for that app to access their Google Drive or GitHub resources on their behalf. What it returns is an access token for resource access, and that token alone can’t tell you exactly who the user is.

OpenID Connect (OIDC) is an authentication layer on top of it. “Sign in with Google” and “Sign in with GitHub” are this. Alongside OAuth’s access token, it also issues an ID Token (in JWT format) carrying the user’s identity. The app verifies this ID Token to confirm who the user is and create a login session.

sequenceDiagram
    autonumber
    actor User as User
    participant App as Application
    participant IdP as Identity Provider (e.g. Google)

    User->>App: Click 'Sign in with Google'
    App->>IdP: Auth request (redirect to consent)
    User->>IdP: Enter credentials and grant consent
    IdP-->>App: Authorization code
    App->>IdP: Exchange code for tokens
    IdP-->>App: access token (authz) + ID Token (authn, JWT)
    Note over App: Verify ID Token to confirm user identity

To put it plainly: delegating permission is OAuth 2.0, confirming identity is OIDC. That’s why “logging in with OAuth” is imprecise.

SSO

SSO (single sign-on, one login for many services) is less an authentication “method” than an experience. Log in once and you use multiple connected systems without logging in again. What holds it up is a central identity provider (Okta, Google Workspace, and the like) and an identity protocol that vouches for the user between systems.

The two representative protocols are SAML 2.0 (Security Assertion Markup Language) and OIDC.

AspectSAML 2.0OIDC
Data formatXMLJSON / JWT
Primary useEnterprise, legacyModern web/mobile, cloud

SAML 2.0 is XML-based and relatively heavy, but it has long been entrenched in enterprise and legacy environments. OIDC is JSON/JWT-based, lighter, and friendly to modern web and mobile apps. Since the OIDC from the previous section also serves as an SSO protocol, authentication delegation and SSO connect into one line.

Closing

The confusion turned out to be, in the end, blurring two questions: authentication or authorization, and where the proof lives. Basic, Digest, and API Key resend the proof every time. Session and Token prove once and carry it forward, while OAuth, OIDC, and SSO borrow the proof from someone else altogether. Rather than memorizing tool names, figuring out which of the two my actual problem sits on came first. Once I lined them up, the terms finally fell into place.

See also