Written by Jason Xie on Feb 11, 2024.
AWS Cognito Authentication in Bun with ElysiaJS
A guide on how to set up AWS Cognito authentication in Bun with ElysiaJS
- Setup bearer and add a handler function that will be our authentication middleware to ElysiaJS
import bearer from "@elysiajs/bearer";
// import AuthMiddleware from ...
const router = new Elysia();
router.get("/health", HealthController.getHealth);
router.use(bearer());
router.onBeforeHandle([AuthMiddleware]);
router.get("/health-auth", HealthController.getHealth);
- Write the code for the AuthMiddleware
Before Feb 11, 2024
import jwt, { JwtPayload } from "jsonwebtoken";
import jwkToPem from "jwk-to-pem";
const getJwk = async (token: string) => {
const decoded = jwt.decode(token, { complete: true }) as JwtPayload;
const tokedKid = decoded.header.kid;
const jwkUrl = decoded.payload.iss + "/.well-known/jwks.json";
const jwks = await fetch(jwkUrl).then((res) => res.json());
const jwk = jwks.keys.find((key: any) => key.kid === tokedKid);
if (!jwk) throw new Error("JWK not found");
return jwk;
};
export const AuthMiddleware = async (context: any) => {
try {
const { bearer } = context;
if (!bearer) throw new Error("No token provided");
const jwk = await getJwk(bearer);
const publicKey = jwkToPem(jwk);
const payload = jwt.verify(bearer, publicKey, { algorithms: ["RS256"] });
context.userClaims = payload;
} catch (error: any) {
console.error("Token is invalid: ", error.message);
return createResponse(401, { error: { message: "Unauthorized" } });
}
};
After Feb 11, 2024 or when the fix is merged
Refer to the following links for more information:
- https://github.com/awslabs/aws-jwt-verify/issues/154
- https://github.com/awslabs/aws-jwt-verify/pull/155
import { CognitoJwtVerifier } from "aws-jwt-verify";
const cognitoJwtVerifier = CognitoJwtVerifier.create({
userPoolId: process.env.AWS_COGNITO_USER_POOL_ID as string,
tokenUse: "access",
});
export const AuthMiddleware = async (context: any) => {
try {
const { bearer } = context;
if (!bearer) throw new Error("No token provided");
const payload = await cognitoJwtVerifier.verify(bearer, {
clientId: process.env.AWS_COGNITO_USER_CLIENT_ID as string,
});
context.userClaims = payload;
} catch (error: any) {
console.error("Token is invalid: ", error.message);
return createResponse(401, { error: { message: "Unauthorized" } });
}
};
- Results
No Auth
With Auth