Created
December 27, 2021 19:26
-
-
Save jiyuhan/88af39d5e1fb94c6c138246c0cf61b90 to your computer and use it in GitHub Desktop.
JWT verifier using JWKS in Cognito
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
steps for verifying JWT through JWKS