forked from auth0/jwt-handbook-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhs256.js
65 lines (52 loc) · 1.87 KB
/
hs256.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import sha256 from './sha256.js';
import hmac from './hmac.js';
import { stringToUtf8, isString, b64, unb64 } from './utils.js';
export default function jwtEncode(header, payload, secret) {
if(typeof header !== 'object' || typeof payload !== 'object') {
throw new TypeError('header and payload must be objects');
}
if(!isString(secret)) {
throw new TypeError("secret must be a string");
}
header.alg = 'HS256';
const encHeader = b64(JSON.stringify(header));
const encPayload = b64(JSON.stringify(payload));
const jwtUnprotected = `${encHeader}.${encPayload}`;
const signature =
b64(hmac(sha256, 512, secret, stringToUtf8(jwtUnprotected), true));
return `${jwtUnprotected}.${signature}`;
}
export function jwtVerifyAndDecode(jwt, secret) {
if(!isString(jwt) || !isString(secret)) {
throw new TypeError('jwt and secret must be strings');
}
const split = jwt.split('.');
if(split.length !== 3) {
throw new Error('Invalid JWT format');
}
const header = JSON.parse(unb64(split[0]));
if(header.alg !== 'HS256') {
throw new Error(`Wrong algorithm: ${header.alg}`);
}
const jwtUnprotected = `${split[0]}.${split[1]}`;
const signature =
b64(hmac(sha256, 512, secret, stringToUtf8(jwtUnprotected), true));
return {
header: header,
payload: JSON.parse(unb64(split[1])),
valid: signature == split[2]
};
}
if(process.env.TEST) {
const secret = 'secret';
const encoded = jwtEncode({}, {sub: "[email protected]"}, secret);
const decoded = jwtVerifyAndDecode(encoded, secret);
console.log(`Encoded: ${encoded}`);
console.log(`Decoded: ${JSON.stringify(decoded)}`);
if(!decoded.valid) {
console.log('hs256: test failed');
process.exit(-1);
} else {
console.log('hs256: all tests passed');
}
}