UNPKG

dm-tools

Version:
129 lines (117 loc) 3.29 kB
import fs from 'node:fs'; import jwt from 'jsonwebtoken'; import Router from '@koa/router'; import {JWT_TOKEN_SECRET} from '../util/secret'; import log from '../util/logger'; /** * Load keys to sign token and verify it. * In a real app the authentication would be performed on a separate server. */ let privateKey: string; let publicKey: string; try { log.info('Loading keys'); publicKey = fs.readFileSync('./key/jwt.pub', 'utf8'); privateKey = fs.readFileSync('./key/jwt.key', 'utf8'); log.info('Loaded keys'); } catch (err) { log.error('Unable to load keys'); process.exit(-1); } /** * Define sample JWT controller. */ export const routerJWT = new Router({prefix: '/api/v1'}); /** * Sign JWT using a secret, return using a cookie. */ routerJWT.post('/login/secret', async (ctx) => { const user = ctx.request.body.name; const jwtToken = jwt.sign( {name: user, exp: Math.floor(Date.now() / 1000) + 5}, JWT_TOKEN_SECRET, ); ctx.cookies.set('jwt', jwtToken); ctx.body = {jwt: jwtToken}; }); /** * Sign JWT using a private SSL key, return using a cookie. */ routerJWT.post('/login/key', async (ctx) => { try { const user = ctx.request.body.name; const jwtToken = jwt.sign( {name: user, exp: Math.floor(Date.now() / 1000) + 20}, privateKey, {algorithm: 'RS256'}, ); ctx.cookies.set('jwt', jwtToken); ctx.body = {jwt: jwtToken}; } catch (err) { ctx.log.error('Failed to sign key'); } }); /** * Verify JWT using a secret, using a cookie. */ routerJWT.get('/protected/secret', async (ctx) => { try { const jwtToken = ctx.cookies.get('jwt') ?? ''; process.stdout.write(`jwt: ${jwtToken}\n`); const jwtDecoded = jwt.verify(jwtToken, JWT_TOKEN_SECRET); if (jwtDecoded['name'] === 'Rajinder') { ctx.body = 'Passed'; } else { ctx.log.error('Invalid User'); ctx.throw(403, 'Invalid User'); } } catch (ex) { ctx.log.error('Invalid JWT token'); ctx.throw(401, 'Invalid JWT token'); } }); /** * Verify JWT using a SSL public key, using a cookie. */ routerJWT.get('/protected/key', async (ctx) => { const jwtToken = ctx.cookies.get('jwt') ?? ''; ctx.log.info('jwt: ', jwtToken); jwt.verify( jwtToken, publicKey, {algorithms: ['RS256']}, function (err, jwtDecoded) { // if token alg != RS256, err == invalid signature if (jwtDecoded && jwtDecoded['name'] === 'Rajinder') { ctx.body = 'Passed'; } else { log.error('Invalid User'); ctx.throw(401, 'Invalid User'); } }, ); }); /** * Verify JWT using a SSL public key, using bearer header. * Authorization: Bearer xx.yy.zz */ routerJWT.get('/protected/bearer', async (ctx) => { const bearerToken = ctx.get('Authorization'); const tok = (bearerToken && bearerToken.split(' ')) ?? []; const jwtToken = tok[1]; ctx.log.info('jwt: ', jwtToken); jwt.verify( jwtToken, publicKey, {algorithms: ['RS256']}, function (err, jwtDecoded) { // if token alg != RS256, err == invalid signature if (jwtDecoded && jwtDecoded['name'] === 'Rajinder') { ctx.body = 'Passed'; } else { ctx.log.error('Invalid User'); ctx.throw(401, 'Invalid User'); } }, ); });