Auth as a Microservice
How I learned to stop worrying and love JWT
In the Beginning
Backend
Backend users user_roles roles
todos
CREATE TABLE todos (
id INT NOT NULL,
text TEXT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY (id),
CONSTRAINT todos_fk_1 FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE
);
Backend
GET /login
HTML
Backend
POST /login
302 + Session
ID
Session
user
42
users
Backend
GET /todos +
Session ID
HTML
Session
user
42
todos
SELECT * FROM todos WHERE user_id = 42;
What about everything else?
● Works on SPAs and Mobile
● Session ID is the user identifier
● Generally hard to steal or forge
● Uses simple HTTP cookies
The Pain
● Stateful
● Potentially requires session replication
● Session pinning
● Harder to scale since every instance runs everything
● One big database
User API
Todo API
User API
Todo API
users
todos
User API
users user_roles roles
Todo API
todos
CREATE TABLE todos (
id INT NOT NULL,
text TEXT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY (id)
);
User API
POST /login
???
User API
POST /login
???
user
42
users
User API
POST /login
User as JSON
user
42
users
{
"user": {
"id": 42,
"name": "Brian Pontarelli",
"email": "brian@inversoft.com",
"roles": ["admin"]
}
}
user
42 Todo API
GET /todos?user_id=42
JSON todos
Danger Will Robinson!
user
1 Todo API
GET /todos?user_id=1
JSON todos
X Get milk
Haha - His wife is gonna be pissed
Haha - Her husband is gonna be pissed
User API
Todo API
users
todos
user
user
T
T
T
User API
Todo API
users
todos
user
user
T
T
T
GET /token/T User as JSON
Tokens
● There must be a User -> Token mapping
● In memory or in database
● Makes the User API slightly stateful
● Can be very chatty
● Couples the User API to EVERYTHING (almost)
User API
Todo API
users
todos
user
user
J
W
T
J
W
T
J
W
T
JWT
● JSON Web Tokens
● Signed with a public/private key pair
● Can be validated by Todo API without calling User API
● Contains roles
JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0
ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZ
S5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy
0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM
3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9s
ZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP
04kZo
JWT Header
{
"typ": "JWT",
"alg": "RS256"
}
JWT Body
{
"iss": "inversoft.io",
"exp": 1300819380,
"sub": "19016b73-3ffa-4b26-80d8-aa9287738677",
"name": "Brian Pontarelli",
"roles": ["RETRIEVE_TODOS"]
}
select * from todos where user_id =
‘19016b73-3ffa-4b26-80d8-aa9287738677’;
Code!
Deleting Users?
delete from users where user_id = 42;
Oops! No ON DELETE CASCADE
User API
Todo API
users
todos
DELETE
DELETE
DELETE
DELETE
User API
Todo API
users
todos
DELETE DELETE
Event
Webhook
DELETE
Code!

Auth as a microservice