Skip to content

Instantly share code, notes, and snippets.

@limitless-dev
Last active July 15, 2023 23:13
Show Gist options
  • Save limitless-dev/e0dcce77b5ab8840d5906d1378662ad2 to your computer and use it in GitHub Desktop.
Save limitless-dev/e0dcce77b5ab8840d5906d1378662ad2 to your computer and use it in GitHub Desktop.
Auth0 Guard with GraphQL in NestJS
/*
---------------
.env
---------------
AUTH0_JWKS_URI=https://your-domain.auth0.com/.well-known/jwks.json
AUTH0_AUDIENCE=https://your-audience.com
AUTH0_ISSUER=https://your-domain.auth0.com/
AUTH0_DOMAIN=your-domain.auth0.com
*/
import {
Injectable,
ExecutionContext,
UnauthorizedException,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { expressjwt, GetVerificationKey } from 'express-jwt';
import { expressJwtSecret } from 'jwks-rsa';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class GqlAuth0Guard {
constructor(private readonly configService: ConfigService) {}
async canActivate(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context).getContext();
// Define your JWKS URL (provided by Auth0)
const jwksUri = this.configService.get('AUTH0_JWKS_URI');
// Define your Auth0 audience and domain
const audience = this.configService.get('AUTH0_AUDIENCE');
const issuer = this.configService.get('AUTH0_ISSUER');
// const domain = this.configService.get('AUTH0_DOMAIN');
// Setup express-jwt and jwksRsa
const expressJwtCheck = expressjwt({
secret: expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: jwksUri,
}) as GetVerificationKey,
audience: audience,
issuer: issuer,
algorithms: ['RS256'],
});
// Run the express-jwt middleware in our guard context
const isAuthorized = await new Promise((resolve, reject) => {
expressJwtCheck(ctx.req, ctx.res, (err: any) => {
if (err) {
const message =
err.name === 'UnauthorizedError' ? err.message : 'Unauthorized';
reject(new UnauthorizedException(message));
} else {
resolve(true);
}
});
});
if (isAuthorized) {
// below commented code is for getting user info from auth0
// but has rate limit of 5 requests per minute
// try {
// const token = ctx.req.headers.authorization.split(' ')[1];
// const response = await axios.get(`https://${domain}/userinfo`, {
// headers: { Authorization: `Bearer ${token}` },
// });
// console.log(response.data);
// ctx.req.user = response.data;
// } catch (error) {
// console.log('userinfo error: ', error);
// }
console.log('ctx.req.auth: ', ctx.req.auth);
}
return isAuthorized;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment