BlogJWT for Beginners: A Complete Guide to JSON Web Tokens
·Updated July 7, 2026·14 min read·JWTSecrets Team

JWT for Beginners: A Complete Guide to JSON Web Tokens

Everything a developer needs to understand JWTs — structure, signing, validation, security pitfalls, and free tools to get started.

JWT for Beginners: A Complete Guide to JSON Web Tokens

If you have ever logged into a web app and seen a long string of characters in your browser's developer tools, you have probably encountered a JWT. This guide explains what they are, how they work, and how to use them safely.

What Is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe string that carries claims (statements about a user) between parties. JWTs are commonly used for authentication: after you log in, the server gives you a JWT, and you send it with every subsequent request.

A JWT looks like this:

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEyM30.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

It has three parts separated by dots: header, payload, and signature.

The Three Parts Explained

Header

{ "alg": "HS256", "typ": "JWT" }

Tells the verifier which algorithm was used to sign the token.

Payload (Claims)

{ "userId": 123, "role": "user", "exp": 1712345678 }

Contains data about the user. Standard claims include sub (subject), iat (issued at), and exp (expiration). Never put sensitive data in the payload — it is only base64-encoded, not encrypted.

Signature

The signature proves the token has not been tampered with. It is computed as:

HMAC-SHA256(base64url(header) + "." + base64url(payload), secret)

Only someone with the secret can produce a valid signature.

How JWT Login Works

1. User submits username and password

2. Server validates credentials

3. Server creates a JWT signed with its secret and returns it

4. Client stores the JWT (cookie or memory)

5. Client sends Authorization: Bearer with each request

6. Server verifies the signature and reads the claims — no database lookup needed

This stateless design scales well but requires careful secret management.

Generating Your First Secret

Before you can sign tokens, you need a secret key. Open the JWT Secret Generator, click Generate, and copy the 256-bit key.

Store it as an environment variable:

JWT_SECRET=your-64-char-hex-key

Signing a Token (Node.js)

const jwt = require('jsonwebtoken');
const token = jwt.sign(
  { userId: 123, role: 'user' },
  process.env.JWT_SECRET,
  { algorithm: 'HS256', expiresIn: '1h' }
);

Or build one visually with the JWT Encoder.

Validating a Token

const payload = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ['HS256'],
});

Paste any token into the JWT Validator to check its signature and expiration during development.

Registered vs Custom Claims

JWT defines standard claims (registered claims) that libraries recognize:

ClaimNamePurpose
`sub`SubjectUser ID or identifier
`iss`IssuerWho created the token
`aud`AudienceIntended recipient service
`exp`ExpirationUnix timestamp when token expires
`iat`Issued AtWhen the token was created
`nbf`Not BeforeToken not valid before this time

You can add custom claims like role, permissions, or tenantId. Keep the payload small — JWTs are sent with every request, and large payloads increase bandwidth and latency.

Where to Store Tokens on the Client

StorageXSS RiskCSRF RiskRecommendation
localStorageHighLowAvoid for auth tokens
sessionStorageHighLowAvoid for auth tokens
Memory (variable)MediumLowOK for SPA during session
httpOnly cookieLowMediumBest default — add CSRF protection

For single-page apps, the industry trend is httpOnly Secure SameSite cookies for refresh tokens and short-lived access tokens in memory.

Common Beginner Mistakes

1. Trusting decoded tokens without verificationjwt.decode() does not check the signature

2. Storing sensitive data in the payload — JWTs are readable by anyone who has the token

3. No expiration — tokens without exp remain valid forever

4. Using alg: none — never accept unsigned tokens in production

5. Sharing secrets between environments — use separate keys for dev, staging, and prod

Building a Complete Auth Flow

Here is a minimal end-to-end flow you can test today:

1. Generate a 256-bit secret with the JWT Secret Generator

2. Set JWT_SECRET in your .env file

3. Create a login endpoint that signs a token after credential validation

4. Protect API routes with middleware that calls jwt.verify()

5. Return 401 for missing or invalid tokens; 403 for valid tokens with insufficient permissions

// Login handler (simplified)
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body.email, req.body.password);
  if (!user) return res.status(401).json({ error: 'Invalid credentials' });
  const token = jwt.sign(
    { sub: user.id, role: user.role },
    process.env.JWT_SECRET,
    { algorithm: 'HS256', expiresIn: '1h' }
  );
  res.json({ token });
});

Test the full loop with the JWT Encoder and JWT Validator before wiring up your database.

Framework Integration Notes

Most web frameworks have JWT plugins or middleware:

  • Express: express-jwt or manual middleware with jsonwebtoken
  • Fastify: @fastify/jwt
  • Django: djangorestframework-simplejwt
  • Spring Boot: spring-boot-starter-oauth2-resource-server

Regardless of framework, the validation rules are the same: verify signature, check expiration, validate issuer and audience.

When JWTs Are Not the Right Choice

JWTs excel at stateless authentication between services, but they are not always ideal:

  • Session-heavy apps with immediate revocation needs may prefer server-side sessions
  • Opaque tokens stored in Redis give instant revocation without waiting for expiry
  • First-party mobile apps sometimes use refresh-token-only flows with short access tokens

Understand the tradeoffs before committing to JWTs for your entire auth architecture.

HS256 vs RS256

  • HS256 — one shared secret signs and verifies. Simple, fast, good for monoliths.
  • RS256 — private key signs, public key verifies. Better for microservices.

See the HS256 vs RS256 comparison for a quick decision, or read the full in-depth guide when you are ready to choose.

Security Essentials

1. Use a 256-bit random secret — not a password

2. Set short expiration times (15–60 minutes)

3. Store secrets in environment variables, not source code

4. Always verify signatures — never just decode

5. Use httpOnly cookies instead of localStorage

See the JWT Best Practices Checklist for the complete list.

Free Tools to Practice

ToolWhat It Does
[JWT Secret Generator](/tools/jwt-secret-generator)Create signing keys
[JWT Encoder](/tools/jwt-encoder)Build and sign tokens
[JWT Validator](/tools/jwt-validator)Verify signatures and inspect claims
[Hash Generator](/tools/hash-generator)Understand SHA-256 used in HMAC

What to Read Next

Written by

JWTSecrets Team

Editorial Team

The JWTSecrets editorial team writes practical guides on JWT authentication, cryptographic key management, and browser-based security tooling. Our content is reviewed against IETF RFCs and current library documentation.