.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF

JWTs: Encrypted? JSON? Client-Side Use? (.NET + React)

TL;DR Standard JWTs are signed (JWS) not encrypted; the header & payload are Base64Url-encoded JSON. Use HTTPS for transport confidentiality, keep sensitive data out of the payload, and protect APIs with [Authorize]. React can decode claims to show/hide UI, but the server enforces security.

Are JWTs Encrypted?

No — not by default. A typical JWT is a signed token (JWS), which guarantees integrity (no tampering) but does not hide the payload. Anyone holding the token can Base64-decode its header and payload.

ConceptWhat it providesVisible to client?
JWS (signed JWT)Authenticity & integrity (valid signature, issuer, audience, expiry)Yes (payload readable)
JWE (encrypted JWT)Confidentiality (payload is unreadable without key)No (payload hidden)
HTTPS/TLSEncrypts data in transit end-to-endN/A (transport layer)

JWT Structure

A JWT has three Base64Url-encoded parts separated by dots:

<header>.<payload>.<signature>

Example (truncated):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxIiwiZW1haWwiOiJ0cmFjZXlAa2F0bWFpZC5jby51ayIsInJvbGUiOiJBZG1pbiIsImV4cCI6MTcyOTgwMTEyMn0.
hKJ6E5qH6x4PV9FyT8h5xUIY5F4gQwF6Nq4Zx1Bih8I

Header JSON

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

Payload JSON

{
  "sub": "1",
  "email": "bob@example.com",
  "role": "Admin",
  "exp": 1729801122
}

Are JWTs JSON Once Decoded?

Yes. The header and payload are literally JSON documents after Base64Url decoding. The third part is a binary signature (also Base64Url-encoded).

Decode in the Browser (demo)

<script>
function base64UrlToJson(str) {
  const b64 = str.replace(/-/g, '+').replace(/_/g, '/');
  const json = atob(b64);
  return JSON.parse(json);
}

const token = "<your.jwt.here>";
const [h, p] = token.split('.');
console.log("Header:", base64UrlToJson(h));
console.log("Payload:", base64UrlToJson(p));
</script>

How React Uses the Token

React doesn’t enforce security—that’s the API’s job—but it can decode claims to control UI and routes:

// Show/hide UI based on role
import jwtDecode from "jwt-decode";
const token = localStorage.getItem("katmaid_token");
const user = token ? jwtDecode(token) : null;

{user?.role === "Admin" && <NavLink to="/admin">Admin Panel</NavLink>}

// Basic route guard
import { Navigate } from "react-router-dom";
function Protected({ children }) {
  const t = localStorage.getItem("katmaid_token");
  if (!t) return <Navigate to="/login" replace />;
  const u = jwtDecode(t);
  if (u.exp * 1000 < Date.now()) return <Navigate to="/login" replace />;
  return children;
}

ASP.NET Core: Validation Recap

Once you configure AddAuthentication().AddJwtBearer(...) and add UseAuthentication()/UseAuthorization(), attributes do the rest:

// Anyone with a valid token
[Authorize]
public IActionResult Get() => Ok();

// Only users whose token contains role "Admin"
[Authorize(Roles = "Admin")]
public IActionResult Update(...) => Ok();

// Public
[AllowAnonymous]
public IActionResult Login(...) => Ok();

What If I Want Encryption Too (JWE)?

ASP.NET Core doesn’t do JWE out of the box. You’d sign (JWS) and then encrypt (JWE) with a library (e.g. Jose.JWT), and add custom decryption before validation. Usually HTTPS + JWS is enough.

// Jose.JWT example (symmetric encryption)
    using Jose;
    using System.Text;

    var payload = new { sub = "1", email = "bob@example.com" };
    var key = Encoding.UTF8.GetBytes("SuperSecretEncryptionKey123!5#");

    // Encrypt (A256GCM)
    string jwe = JWT.Encode(payload, key, JweAlgorithm.DIR, JweEncryption.A256GCM);

    // Decrypt
    var json = JWT.Decode(jwe, key);

Best-Practice Checklist

✔ Use HTTPS everywhere
✔ Keep JWTs minimal; no secrets in payload
✔ Validate issuer, audience, signature, lifetime
✔ Set short expiries (e.g., 15–120 min) + refresh flow if needed
✔ Store signing keys securely (Key Vault / env vars); rotate
✔ Use role/permission claims for authz on the server
✔ In SPAs, protect routes/UI but always re-check on the server
✔ Prefer HttpOnly cookies to reduce XSS token theft (trade-offs apply)