What is Self Validating Tokens?
Adarsh Mishra
Innovative Software Engineer | Rust, C++, Java | Expert in Distributed Systems, Microservices | Passionate about High-Level Design & Optimization |
In our last post, we dove into the world of Authentication and Authorization, breaking down how these twin forces keep our digital spaces secure. But hold on—we’re just getting started! There’s still a lot more ground to cover.
If you’re already familiar with the basics, you’re ahead of the game. But if you missed it, no worries! You can catch up on the foundation we laid here: Understanding Authentication and Authorization.
Why Do We Even Need Tokens?
Imagine you’re at an all-you-can-eat buffet, and every time you go back for more food, the staff asks for your ID. Annoying, right? Instead, they give you a wristband when you enter, so you just flash it, and they know you’re good to go. That wristband is like a token in the digital world. It’s a way to say, “Hey, I’ve already proven who I am; let me do my thing.”
But here’s a thought—every time you flash that wristband, should the staff call up some central office to verify it? That would slow things down, just like how querying a database every time you verify a token could increase latency. Even if you store data in a cache to make things faster, you still need to sync it with the database, adding a network hop. Not cool.
But what if we could validate the token without asking anyone else? Like, not even the database. Just the good ol’ CPU doing its job.
The Difference Between Encoding and Hashing
Before we jump into the magic trick of validating tokens, let’s clear up the difference between encoding and hashing.
The Magic of Self-Validating Tokens
Here’s an idea: what if we stuff all the important details, like user ID and expiry time, directly into the token? Sounds smart, but hold on.
领英推荐
Approach 1: The Base64 Bandit
Imagine we create a JSON like this:
{
"user_id": 12345,
"email_id": "[email protected]",
"role": ["admin"],
"expiry_time": "Thursday 20th Feb 2025"
}
We base64 encode it and send it off as a token. But wait—what’s stopping someone from opening up their browser’s inspect tool, tweaking the expiry time, and becoming an eternal admin? Yikes!
Approach 2: The Self-Validating Token (a.k.a. JWT)
Now, let’s get clever. What if we encrypt that token with a secret key known only to the server? This way, when a request comes in, the server can decrypt it, check the details, and know it hasn’t been tampered with.
Here’s the recipe:
Server{
login(email, password){
# Check with the database if email and password are correct
value = base64encode({....})
token = encrypt(value, secret)
return token
}
}
In simple terms, encryption is like encoding but with a secret sauce. To decrypt it, you need the same secret sauce. Think of it like how WhatsApp encrypts your chats, and only you and the recipient can read them.
Meet JWT (JSON Web Token)
A JWT is like a superpower token made of three parts: A.B.C.
Here’s how it works:
login(email, password) {
a = base64encode({"algorithm_name": "HS256"})
b = base64encode({
"user_id": 12345,
"email_id": "[email protected]",
"expiry": "Thursday 20th Feb 2025",
"role": ["admin"]
})
c = algorithm_encryption(a + "." + b, secret)
return a + "." + b + "." + c
}
verify_token(token){
a, b, c = token.split(".")
d = decrypt(c, secret)
if d fails: return "Invalid token!"
if (a + "." + b) != d: return "Invalid token!"
return "Token is valid!"
}
No database calls, no extra network hops—just pure, unadulterated CPU power keeping things snappy.