battk
08/10/2019, 6:44 PMsamyt
08/11/2019, 5:56 AMbattk
08/11/2019, 6:31 AMmichoel
08/11/2019, 8:55 AMmichoel
08/11/2019, 8:56 AMmichoel
08/11/2019, 8:56 AMimport * as crypto from './crypto';
export default function encodeJWT_HS256(payload, secret) {
const header = {
alg: 'HS256',
typ: 'JWT',
};
const segments = [];
segments.push(base64UrlEncode(JSON.stringify(header)));
segments.push(base64UrlEncode(JSON.stringify(payload)));
segments.push(signHS256(segments.join('.'), secret));
return segments.join('.');
}
function base64UrlEncode(string) {
const wordArray = crypto.enc.Utf8.parse(string);
const base64 = crypto.enc.Base64.stringify(wordArray);
return base64UrlEscape(base64);
}
function base64UrlEscape(string) {
return string
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
function signHS256(input, secret) {
const hash = crypto.HmacSHA256(input, secret);
const base64 = crypto.enc.Base64.stringify(hash);
return base64UrlEscape(base64);
}
samyt
08/12/2019, 7:16 AMmichoel
08/21/2019, 4:37 AMmichoel
08/21/2019, 4:37 AM// Very simple JWT encoder based loosely on node-jwt-simple
// <https://github.com/hokaccha/node-jwt-simple>
import * as crypto from './crypto-js.min';
const algorithmFunctionMap = {
HS256: crypto.HmacSHA256,
HS384: crypto.HmacSHA384,
HS512: crypto.HmacSHA512,
};
export function encode(payload, secret, algorithm = 'HS256') {
const header = {
alg: algorithm,
typ: 'JWT',
};
const segments = [];
segments.push(base64UrlEncode(JSON.stringify(header)));
segments.push(base64UrlEncode(JSON.stringify(payload)));
segments.push(sign(segments.join('.'), secret, algorithm));
return segments.join('.');
}
export function decode(token, secret) {
if (!token) {
throw new Error('No token supplied');
}
const segments = token.split('.');
if (segments.length !== 3) {
throw new Error('Not enough or too many segments');
}
const headerSeg = segments[0];
const payloadSeg = segments[1];
const signatureSeg = segments[2];
const header = JSON.parse(base64UrlDecode(headerSeg));
const payload = JSON.parse(base64UrlDecode(payloadSeg));
const signingInput = [headerSeg, payloadSeg].join('.');
if (signatureSeg !== sign(signingInput, secret, header.alg)) {
throw new Error('Signature verification failed');
}
if (payload.nbf && Date.now() < payload.nbf * 1000) {
throw new Error('Token not yet active');
}
if (payload.exp && Date.now() > payload.exp * 1000) {
throw new Error('Token expired');
}
return payload;
}
function sign(input, secret, algorithm) {
const cryptoFunction = algorithmFunctionMap[algorithm];
if (!cryptoFunction) {
throw new Error('Algorithm not supported');
}
const hash = cryptoFunction(input, secret);
const base64 = crypto.enc.Base64.stringify(hash);
return base64UrlEscape(base64);
}
function base64UrlDecode(str) {
const unescaped = base64UrlUnescape(str);
const words = crypto.enc.Base64.parse(unescaped);
return crypto.enc.Utf8.stringify(words);
}
function base64UrlUnescape(str) {
str += new Array(5 - (str.length % 4)).join('=');
return str.replace(/\-/g, '+').replace(/_/g, '/');
}
function base64UrlEncode(string) {
const wordArray = crypto.enc.Utf8.parse(string);
const base64 = crypto.enc.Base64.stringify(wordArray);
return base64UrlEscape(base64);
}
function base64UrlEscape(string) {
return string
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
michoel
08/21/2019, 4:38 AMmichoel
08/21/2019, 4:38 AM