Skip to main content

Base64 Encoding Explained: Data URIs, JWTs, and API Authentication

A practical guide to Base64 encoding — how it works, why browsers and APIs use it for data URIs and JWTs, and where it shows up in HTTP authentication headers.

Published
#base64 #encoding #jwt #api #authentication #data-uri

Base64 Encoding Explained: Data URIs, JWTs, and API Authentication

Base64 turns binary data into a string of 64 printable ASCII characters. That sounds trivial, but that one property — "printable ASCII" — is why Base64 shows up in three different corners of everyday web development: embedding images in HTML, signing JSON Web Tokens, and authenticating API requests.

This guide walks through each use case with real examples, so you can recognize Base64 when you encounter it and know exactly what to do.

How Base64 Actually Works

Base64 takes every 3 bytes of input and maps them to 4 characters from the alphabet A–Z, a–z, 0–9, +, /. If the input length isn't a multiple of 3, padding = characters are appended so the output length is always a multiple of 4.

Real example: the string Hi! (3 bytes: 0x48 0x69 0x21) encodes to SGkh.

Here's the bit breakdown:

  • H = 01001000
  • i = 01101001
  • ! = 00100001

Concatenated: 010010000110100100100001

Split into 6-bit groups: 010010 000110 100100 100001 → decimal 18, 6, 36, 33 → S, G, k, h.

Try it yourself at Toolora's Base64 encoder — paste any text and you'll see the exact output plus the byte count.

Because Base64 expands data by roughly 33% (every 3 bytes becomes 4 characters), it is never the right choice for pure compression. Its only job is safe transport.

Data URIs: Embedding Images Without a Network Request

A data URI encodes an entire file as a Base64 string and embeds it directly in HTML or CSS:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ...

The format is data:<mime-type>;base64,<encoded-data>. Browsers parse and render these without making any HTTP request, which eliminates one round-trip per image.

When this actually helps: I used data URIs last year to inline a 14×14 px loading spinner SVG directly into a CSS file. The spinner was 142 bytes raw; as a data URI it became 192 bytes — a 35% overhead — but since it lives in the CSS file that's already being parsed, there's zero extra request. For a spinner that fires immediately on page load, that trade-off is worth it.

When it doesn't help: Google's HTTP Archive data (2024 Web Almanac) shows that data URIs larger than 8 KB consistently hurt Core Web Vitals scores because the inline content blocks HTML parsing. The rule of thumb most teams use: data URIs only for images under 2 KB.

JWTs: Base64URL and Why the Alphabet Changes

JSON Web Tokens look like Base64 but use a slightly different alphabet. Standard Base64 includes + and /, which are URL-reserved characters. JWTs use Base64URL instead: +- and /_, and padding = is stripped entirely.

A JWT has three parts separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1MTIzIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzE5Mzk5OTk5fQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Decode the first segment:

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

Decode the second:

eyJzdWIiOiJ1MTIzIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzE5Mzk5OTk5fQ
→ {"sub":"u123","name":"Alice","iat":1719399999}

The third segment is the cryptographic signature — also Base64URL encoded, but it's a raw byte sequence, not JSON.

Important: Base64URL decoding reveals the header and payload, but it does NOT verify the signature. Anyone can decode a JWT. The signature check is what proves the token wasn't tampered with, and that check requires the secret key or public key on the server side.

To inspect a JWT without trusting a third-party site with your token, use Toolora's JWT decoder — it decodes entirely in your browser, nothing is sent anywhere. For encoding custom payloads into the Base64URL format, the Base64URL encoder handles the alphabet substitution and padding removal automatically.

HTTP Basic Auth: Base64 in the Authorization Header

HTTP Basic Authentication encodes credentials as username:password in Base64 and sends them in a request header:

Authorization: Basic dXNlcjpwYXNzd29yZA==

Decode dXNlcjpwYXNzd29yZA==:

dXNlcjpwYXNzd29yZA== → user:password

That's it. Basic Auth is trivially reversible — Base64 is an encoding, not encryption. Every HTTP request carrying Authorization: Basic ... over plain HTTP exposes the credentials to any network observer. Basic Auth is only acceptable over HTTPS, and even then, rotating to API keys or OAuth tokens is the safer pattern for anything beyond internal tooling.

Bearer tokens (OAuth 2.0, API keys) often look like Base64 strings too, but they're treated as opaque values — the server checks them against a database rather than decoding them locally.

Common Pitfalls

Confusing encoding with encryption. Base64 encoded data is fully readable to anyone. Never store passwords or private keys as "Base64 encoded" and assume they're protected.

Standard vs. Base64URL alphabet. A JWT-style token fed to a standard Base64 decoder will fail because - and _ aren't in the standard alphabet. If you're writing a decoder yourself, check which variant the spec calls for.

Padding errors. Some Base64 implementations strip the trailing = signs; others require them. The RFC 4648 standard makes padding optional in many contexts, but mixing padded and unpadded strings in the same pipeline causes decoding errors. I've spent more than one afternoon debugging an API client that silently stripped = before forwarding a token.

Binary data in JSON. JSON has no native binary type. The standard practice is to Base64-encode any binary field (images, certificates, encrypted blobs) before embedding in JSON. The client must decode it back to bytes before use.

Quick Reference

| Context | Alphabet | Padding | Notes | |---|---|---|---| | Standard Base64 (RFC 4648) | A–Z a–z 0–9 + / | Required | Email attachments, data URIs | | Base64URL (RFC 4648 §5) | A–Z a–z 0–9 - _ | Optional | JWTs, URL parameters | | MIME Base64 | Same as standard | Required + line breaks | Email MIME parts |

When you need to quickly encode or decode a string, Toolora's Base64 encoder handles all three variants and shows the size overhead so you can decide whether inline embedding makes sense for your use case.


Made by Toolora · Updated 2026-06-26