OAuth versus JWT is one of the most common false comparisons in web development. They are not competitors. OAuth is an authorization framework — a set of flows for granting an application access to resources on a user's behalf. JWT is a token format — a compact, signed way to carry claims. You can use OAuth without JWTs, use JWTs without OAuth, or, most often in 2026, use them together. Getting the distinction straight prevents a whole class of design mistakes.
What changed in 2026
- OAuth 2.1 consolidated best practices. The security recommendations that accumulated over the years (PKCE by default, no implicit flow, no password grant) are now the baseline expectation, not optional hardening.
- Sender-constrained tokens gained traction. Techniques that bind a token to a client (so a stolen bearer token is useless elsewhere) moved from niche to recommended for high-value APIs.
- Short-lived access tokens plus refresh tokens are standard. The pattern of minutes-long access tokens with rotating refresh tokens is now the default answer to the JWT revocation problem.
- Cookie storage won for browsers. The community consensus firmed up around secure, httpOnly cookies over localStorage for web token storage.
What OAuth actually is
OAuth 2.0 is a delegation protocol. The classic scenario: you want an app to access your calendar without handing it your account password. OAuth defines the dance that makes this safe. The key players are the resource owner (you), the client (the app), the authorization server (which issues tokens), and the resource server (which holds your data).
In the modern authorization-code flow with PKCE, the app redirects you to the authorization server, you approve the requested scopes, and the app receives an authorization code it exchanges for an access token. The app never sees your password. What OAuth deliberately does not specify is the format of that access token — it could be an opaque random string or a JWT. That is where JWT enters.
What JWT actually is
A JSON Web Token is a self-contained token with three parts: a header, a payload of claims, and a signature. Encoded, it looks like three base64url segments separated by dots.
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.<signature>
The payload might carry the user id, roles, and an expiry. Because the token is signed, the server can verify it has not been tampered with using a secret or public key — no database lookup required. That statelessness is the big appeal: any server holding the verification key can trust the token, which is ideal for distributed systems and horizontal scaling.
The catch is the flip side of statelessness. Because nothing is stored server-side, you cannot simply "delete" a JWT to log someone out. It remains valid until it expires. This revocation gap is the single most important thing to understand before choosing JWTs. Handling it well overlaps with how you throttle and protect endpoints in general, which the rate limiting strategies guide covers in depth.
OAuth vs JWT at a glance
| Aspect |
OAuth 2.x |
JWT |
| What it is |
Authorization framework |
Token format |
| Answers |
Who may access what |
How a claim is carried |
| Stateful? |
Depends on token type |
Stateless by nature |
| Revocation |
Via token introspection or short expiry |
Hard; needs expiry or a blocklist |
| Common pairing |
Often issues JWT access tokens |
Often the token OAuth issues |
| Use alone? |
Yes, with opaque tokens |
Yes, for simple app auth |
When to use which
Reach for OAuth whenever a third party needs delegated access, when you support "sign in with" providers, or when you need scoped, revocable permissions across multiple clients. It is the right tool for anything resembling a public or partner API.
Reach for JWTs when you want stateless verification inside your own system — for example, an access token that many microservices can validate independently. Keep them short-lived and pair them with refresh tokens so the revocation weakness is bounded to minutes.
For a plain first-party app with a single backend, traditional server-side sessions are often simpler and safer than JWTs, and you should not adopt JWTs just because they are fashionable.
Pitfalls
- Treating them as either/or. They operate at different layers.
- Long-lived JWTs. A leaked token stays valid until expiry; keep access tokens short.
- Storing tokens in localStorage. Cross-site scripting can read them. Prefer httpOnly cookies.
- Trusting the
alg header blindly. Pin your algorithm server-side to avoid algorithm-confusion attacks.
- Putting secrets in the payload. A JWT is signed, not encrypted; anyone can read the claims.
FAQ
Is JWT part of OAuth?
Not required, but common. OAuth does not mandate a token format; JWT is one popular choice for the access tokens OAuth issues.
Can I use JWT without OAuth?
Yes. Many apps issue their own JWTs for session-like authentication with no OAuth involved. It is simpler but you own the revocation problem.
How do I revoke a JWT?
You cannot revoke a pure JWT directly. Options are short expiry with refresh tokens, or maintaining a server-side blocklist — which reintroduces the state you were avoiding.
Are JWTs encrypted?
By default, no. A standard JWT is signed for integrity but readable by anyone. Use JWE if you need the payload hidden, and never store secrets in a plain JWT.
Where to go next