Skip to content

Authentication & Tokens Lab

Topical Authority Guide & Developer Workspace

Runs entirely in your browser

This tool executes locally using standard browser APIs (for example window.crypto.getRandomValues or crypto.subtle where applicable). Your input is not transmitted to or stored on a ScriptPulse server. See How Calculations Work.

No data uploaded

Authentication validates a user's identity. Storing and transmitting these credentials requires secure protocols, including tokenized sessions, hashing algorithms, and time-based passwords.

Topic Overview

Modern web apps rely on stateless authentication systems to scale. JSON Web Tokens (JWT) allow servers to verify user claims securely without database queries on every HTTP request.

Securing credentials requires using slow hashing functions, multi-factor authentication (MFA), and secure session tokens.

Beyond tokens themselves, authentication systems depend on secure credential storage (password hashing) and on unique identifiers for sessions, users, and API keys — this hub covers all three as one connected topic, since a real login flow touches each of them.

Core Concepts: JWT Anatomy and Credential Storage

A JSON Web Token consists of three base64url-encoded parts separated by periods: the Header (declares the signing algorithm), the Payload (claims — issuer, subject, expiration, and any custom application data), and the Signature (verifies the token hasn't been tampered with since issuance). Because the header and payload are only encoded, not encrypted, anyone who has the token can decode and read its contents — the signature protects integrity, not confidentiality. If you need to keep the token's contents secret from whoever holds it, that requires actual encryption (the JWE format) rather than the signed-only JWS format described here — see the Encryption hub for confidentiality and key-management fundamentals beyond what signing alone provides.

Storing user passwords is a separate problem from tokens: passwords must never be stored in plaintext or reversibly encrypted. Instead, a slow, salted hashing function — bcrypt or Argon2 in current practice — transforms the password into a digest that's computationally expensive to reverse, so a database breach doesn't directly expose usable credentials. Speed here is a liability, not a feature: a hashing function fast enough for convenience is also fast enough for an attacker to brute-force offline. This hub covers password hashing specifically for credential storage; for general-purpose hashing, checksums, and HMAC-based integrity verification unrelated to authentication, see the Hashing & Integrity hub.

Multi-factor authentication typically adds a Time-Based One-Time Password (TOTP) as a second factor: both the client app and the server independently compute a code from a shared secret and the current Unix time (in 30-second steps), using HMAC under the hood. Because both sides derive the same code from the same inputs without transmitting the secret itself, TOTP remains secure even if the primary password database is later compromised.

Practical Application: Building and Testing a Token-Based Login Flow

A typical login-and-session flow looks like this: hash the user's chosen password before storing it — use the Bcrypt Hasher during development to confirm your server-side hashing configuration produces the cost factor you expect. Verify password strength before accepting it in the first place with the Password Analyzer, and if you need to generate a strong default or test password, use the Password Generator rather than typing one by hand.

Once credentials are verified, issue a session token. Use the JWT Generator to build a signed token with the claims your application needs (subject, expiration, roles), then the JWT Inspector to confirm the token decodes to exactly the claims you intended before shipping the flow. If you need to test how your application handles a modified or expired token, the JWT Claims Editor lets you repackage an existing token's claims without regenerating it from scratch.

For API keys or bearer tokens outside the JWT flow, the Token Generator produces cryptographically random values in common formats. If your login flow includes a second factor, use the OTP Code Generator to produce and verify TOTP codes against a shared secret during testing, before wiring up a real authenticator app integration.

Any of these tokens or session records typically need a unique identifier — see the Unique Identifiers section below for choosing between UUID, ULID, and NanoID for that purpose.

Common Mistakes and Troubleshooting

Mistake: putting sensitive data (passwords, full credit card numbers, private keys) directly in a JWT payload. Because the payload is only base64url-encoded, not encrypted, this data is trivially readable by anyone who intercepts or is handed the token. Fix: keep JWT payloads limited to non-sensitive claims needed for authorization decisions, and look up sensitive data server-side using the token's subject claim instead.

Mistake: issuing tokens with no expiration, or an expiration far longer than the session actually needs. A stolen token with no expiry is valid indefinitely. Fix: set a short expiration (the exp claim) appropriate to the session's actual risk profile, and use a refresh-token pattern for longer-lived sessions rather than one long-lived access token.

Mistake: using a weak or hardcoded JWT signing secret, or reusing the same secret across environments. A weak HMAC secret can be brute-forced offline; a leaked shared secret compromises every environment that uses it. Fix: use a cryptographically random secret of sufficient length, or an asymmetric RS/ES algorithm with properly separated keys, generated and stored independently per environment.

Troubleshooting: if TOTP codes intermittently fail to validate even with the correct secret, check clock synchronization first — TOTP is time-window based, and a server or client clock skewed by more than roughly 30 to 60 seconds computes a different code than the other side expects.

Standards and Specifications

JSON Web Tokens are defined by RFC 7519, with the underlying signing mechanism defined by RFC 7515 (JSON Web Signature), key representation by RFC 7517 (JSON Web Key), and the encrypted-token variant by RFC 7516 (JSON Web Encryption) for cases where confidentiality, not just integrity, is required.

Time-Based One-Time Passwords are defined by RFC 6238, built on top of HMAC-Based One-Time Passwords (RFC 4226) and HMAC itself (RFC 2104).

NIST SP 800-63B is the current authoritative guidance on digital identity and authenticator requirements, including specific password-composition and storage recommendations that supersede older, less effective advice like mandatory periodic password rotation.

OAuth 2.0, the authorization framework underlying most modern token-based login flows, is defined by RFC 6749; OpenID Connect, which adds an identity layer on top of OAuth 2.0, is defined by the OpenID Foundation's own specification rather than an RFC.

Decision Guidance: Choosing the Right Mechanism

For password hashing, prefer Argon2 for new systems where you control the implementation — it is the more modern, memory-hard design and the winner of the 2015 Password Hashing Competition — but bcrypt remains a reasonable, well-tested choice where your stack has strong native bcrypt support and no compelling reason to switch. See the Bcrypt vs Argon2 comparison for the full tradeoff.

For session state, choose JWTs when you need stateless verification across multiple services without a shared session store; choose traditional server-side session cookies when you need instant revocation or your architecture is a single monolith where a shared session store is not a bottleneck. See the JWT vs Cookies comparison.

For federated identity between organizations, SAML remains common in enterprise and legacy environments; OAuth 2.0/OpenID Connect is the standard choice for modern consumer-facing and API-driven applications. See the OAuth2 vs SAML comparison.

Unique Identifiers for Sessions, Resources, and Distributed Systems

Authentication systems need unique identifiers constantly — session IDs, user IDs, API keys, audit-log entries — and the three most common choices are UUID (specifically UUIDv4, fully random), ULID (lexicographically sortable, embeds a timestamp), and NanoID (compact, URL-safe, customizable alphabet and length).

The practical difference that matters most: a UUIDv4 gives no information about creation order and is fixed at 128 bits (36 characters in its standard string form); a ULID sorts naturally by creation time when used as a database key, which UUIDv4 does not, causing index fragmentation in some databases at high insert volume; a NanoID is shorter and more compact for cases like URL slugs where the standard UUID format is unnecessarily long. Use the UUID Generator, ULID Generator, and Nano ID Generator to produce and compare real examples of each.

See the UUID vs ULID vs NanoID comparison for the full tradeoff breakdown, including which one fits high-write-volume database keys, public-facing URLs, and security-token use cases best.

Related Developer Hubs

Explore neighboring topics that connect to this one.

Frequently Asked Questions

Are JWT claims encrypted by default?
No. JWT payloads are only Base64URL-encoded, which is a plaintext conversion. Anyone can decode and read JWT contents; never put passwords or sensitive data inside payloads.
How do TOTP generators stay in sync?
TOTP client apps and server backends calculate codes using the same shared secret and coordinate their steps with the global Unix time clock, tolerating short offsets.
What is the difference between hashing and encrypting a password?
Hashing is one-way and irreversible by design — the same password always produces the same hash, but the hash can't be converted back to the password. Encryption is reversible with the right key. Passwords should always be hashed, never encrypted, because encryption implies the plaintext could be recovered, which is exactly what you don't want for stored credentials.
Why is bcrypt or Argon2 preferred over SHA-256 for passwords?
General-purpose hash functions like SHA-256 are designed to be fast, which is exactly the wrong property for password storage — a fast hash lets an attacker with a stolen database try billions of guesses per second. Bcrypt and Argon2 are deliberately slow and, for Argon2, memory-hard, making large-scale offline guessing dramatically more expensive.
Should I use UUID, ULID, or NanoID for a new project?
If you need database keys that insert efficiently at scale and want built-in time-ordering, use ULID. If you need the shortest possible identifier for a public URL, use NanoID. If you need a well-known, universally supported standard format with no other requirements, UUIDv4 remains a safe default. See the UUID vs ULID vs NanoID comparison for the full breakdown.
Can a JWT be revoked before it expires?
Not directly — JWTs are stateless and valid until their expiration by design. To support early revocation, applications typically maintain a server-side denylist of revoked token IDs (using the JWT's jti claim) or keep access-token lifetimes short and rely on a revocable refresh token for renewal.
What does OAuth 2.0 actually authenticate?
Strictly speaking, OAuth 2.0 is an authorization framework, not an authentication protocol — it governs granting a client limited access to a resource, not proving user identity. OpenID Connect adds an identity layer on top of OAuth 2.0 specifically to handle authentication; the two are often used together but solve different problems.