- Full Stack Developer, Tech Trainer & Speaker
- Ambassador @Auth0
- Organizer @Vuenos_Aires
^ I will use the help of thinking face
^ 1. The server does not have to keep a record ^ 2. No server session
^ 1. Token could be issued for other server. ^ 2. Perfect for cross domain (no cookies)
^ 1. Reduce data look up ^ horizontally scale ^ No client session
> Standard RFC 7519
^ 1. Base on web standard RFC 7519 ^ Defines A safe way to represent a set of information between two parties
^ 2. All the info is inside (transmit information)
^ 3. NO XML, lighter content
^ 4. Cryptographic Signed ^ Keeps token secure ^ Allows to validate against modifications ^ Hashed message or public/private key pairs
^ 5. Easy to read and parse, humans and machines
^ Token based on encoded JSON
^ Is composed by tree base64 Parts, separated by dots
{
"alg": "HS256",
"typ": "JWT"
}
^ type & algoritm, In this cases hashed message
{
"id": "1234567890",
"name": "John Doe",
"admin": true,
"iss": "https://api.com",
"exp": 1510745797148
}
^ claims, information to exchange public claims
{
"id": "1234567890",
"name": "John Doe",
"admin": true,
"iss": "https://api.com",
"exp": 1510745797148
}
^ reserved claims
const data = base64urlEncode( header ) + '.' +
base64urlEncode( payload )
HMACSHA256(data, 'your_secret_message')
^ encoded header & payload + secret (encrypted) ^ proves identity ^ ensure message can't change
const data = base64urlEncode( header ) + '.' +
base64urlEncode( payload )
HMACSHA256(data, 'your_secret_message')
^ AI OU TI
^ drums sound
POST /login
{
"user": "ianaya89",
"password": "dont-hack-me"
}
const jwt = require('jsonwebtoken')
// POST /login
function login (req, res, next) {
// Validates user credentials...
const payload = { user: 'ianaya89', role: 'admin' }
const token = jwt.sign(payload, 'this_is_super_secret')
res.status(201).send({ token: `Bearer ${token}` })
}
router.post('/login', login)
const jwt = require('jsonwebtoken')
// POST /login
function login (req, res, next) {
// Validates user credentials...
const payload = { user: 'ianaya89', role: 'admin' }
const token = jwt.sign(payload, 'this_is_super_secret')
res.status(201).send({ token: `Bearer ${token}` })
}
router.post('/login', login)
^ The client should save / persist the token
GET /resource
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkiLCJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6ZmFsc2V9.
b99O1RrYbHtWJ3MGZXkdADZkmiLm9HNliRccKxMPDuc
^ Access protected endpoint, The client should save / persist the token
const jwt = require('jsonwebtoken')
// GET /resource
function getResource (req, res, next) {
try {
const payload = jwt.verify(token, 'this_is_super_secret')
}
catch (err) {
return res.sendStatus(401)
}
}
router.get('/resource', getResource)
^ middleware, automatization
const jwt = require('jsonwebtoken')
// GET /resource
function getResource (req, res, next) {
try {
const payload = jwt.verify(token, 'this_is_super_secret')
res.send('π')
}
catch (err) {
return res.sendStatus(401)
}
}
router.get('/resource', getResource)
const jwt = require('jsonwebtoken')
// GET /resource
function getResource (req, res, next) {
try {
const payload = jwt.verify(token, 'this_is_super_secret')
if (payload.role !== 'admin') {
return res.sendStatus(403)
}
res.send('π')
}
catch (err) {
return res.sendStatus(401)
}
}
router.get('/resource', getResource)
^ drums sound
^ there is always a but
^ Forest's mom said
^ Don't store sensitive information
^ JSON Web Encryption allows you to safely encrypt the claims of a token