Last active
July 15, 2023 23:13
-
-
Save limitless-dev/e0dcce77b5ab8840d5906d1378662ad2 to your computer and use it in GitHub Desktop.
Auth0 Guard with GraphQL in NestJS
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
/* | |
--------------- | |
.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