Skip to content

Instantly share code, notes, and snippets.

@jiyuhan
Created December 27, 2021 19:26
Show Gist options
  • Save jiyuhan/88af39d5e1fb94c6c138246c0cf61b90 to your computer and use it in GitHub Desktop.
Save jiyuhan/88af39d5e1fb94c6c138246c0cf61b90 to your computer and use it in GitHub Desktop.
JWT verifier using JWKS in Cognito
import { decode, verify } from 'jsonwebtoken';
import { Request, Response, NextFunction } from 'express';
import { CachedJwks } from '../common/cached-jwks';
import { UserInformationFromToken } from '../models/api/user/user-metadata';
import HttpStatusCode from 'http-status-typed';
import { AWS_CONFIG } from '../variables-config';
import { UNAUTHORIZED_RESPONSE } from '../models/api/shared/unauthorized-response';
import ProfileLogger from '../common/logger';
import { UserService } from '../services/user-service';
import { getCompanyNameAndSuffix } from '../common/group-naming';
const logger = ProfileLogger.newClassLogger('jwt-verifier');
/**
* Followed guidance from
* https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
*/
export async function verifyJwt(req: Request, res: Response, next: NextFunction) {
let token = req.headers['authorization'];
if (!token) {
res.status(HttpStatusCode.UNAUTHORIZED);
return res.json(UNAUTHORIZED_RESPONSE);
}
if (token.startsWith('Bearer ')) {
// Remove Bearer from string
token = token.slice(7, token.length);
}
try {
// step 1
const { header, payload } = decode(token, { complete: true }) as {
header: { kid: string; alg: string };
payload: UserInformationFromToken;
};
const jwks = await CachedJwks.get();
const pem = jwks.get(header.kid);
if (pem) {
// step 2
verify(token, pem);
// step 3
if (
payload.exp * 1000 < Date.now() ||
payload.iss !==
`${AWS_CONFIG.AWS_COGNITO_IDP_ENDPOINT}/${AWS_CONFIG.AWS_COGNITO_USER_POOL_ID}` ||
payload.token_use !== 'access'
) {
res.status(HttpStatusCode.UNAUTHORIZED);
return res.json(UNAUTHORIZED_RESPONSE);
}
return next();
}
logger.error('Server error. Could not find the right PEM to decode');
res.status(HttpStatusCode.UNAUTHORIZED);
// even on failure, we need to disguise the root cause here
res.json(UNAUTHORIZED_RESPONSE);
} catch (error) {
logger.warn('Error during jwt verification.', error);
res.status(HttpStatusCode.UNAUTHORIZED);
res.json(UNAUTHORIZED_RESPONSE);
}
}
@jiyuhan
Copy link
Author

jiyuhan commented Dec 27, 2021

steps for verifying JWT through JWKS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment