JWT
JSON Web Token is a specification that defines a way to sign and exchange information.
Like signed cookies the information can be verified and trusted, but not encrypted, so it not for sensitive information.
The Format
JWT consist of 3 parts:
<header>.<payload>.<signature>
Header
Both header and payload are JSON strings that encode as base64 strings.
Header contains two fields, signing algorithm and type:
{
"alg": "HS256",
"typ": "JWT"
}
Payload
Payload contains the actual data, and also some standard fields like exp(expiration time) and sub(subject).
{
"exp": 17266579863,
"sub": "<user id>",
"name": "Alice"
}
All standard field name are shortened to 3 chars to save space. (But json is not a concise format anyway.)
Signature
Signature is computed as following:
HMACSHA256(base64(header) + '.' + base64(payload), secret)
Signing
A minimal implementation:
const crypto = require(crypto)
function generateJWT(payload, secretKey) {
const header = {
alg: 'HS256',
typ: 'JWT'
}
const encodedHeader = btoa(JSON.stringify(header))
const encodedPayload = btoa(JSON.stringify(payload))
const signature = crypto.createHash('sha256', secretKey)
.update(`${encodedHeader}.${encodedPayload}`)
.digest('base64')
return `${encodedHeader}.${encodedPayload}.${signature}`;
}
Verification
Just sign again and compare the signature. The exp value should also
be compared with current timestamp.
Expiration
Token with expration is much securer. The sub in Payload is
designed for this purpose. It should a epoch time in the future.
Revoke a Token
The is no way to revoke a JWT, but you can mantain a blacklist in a kv store or database, and better load it into memory for efficiency.