How to authorize NestJs, GraphQL app using Auth0 and Passport?

How to authorize NestJs, GraphQL app using Auth0 and Passport?


0

I have developed a NestJs graphql app and now I want to authorize all my mutations and queries. Users get authenticated from Auth0. after following this article I have created below files in my project.

AuthModule :

import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [PassportModule.register({ defaultStrategy: 'jwt' })],
  providers: [JwtStrategy],
  exports: [PassportModule, JwtStrategy],
})
export class AuthModule {}

JwtStrategy :

import { passportJwtSecret } from 'jwks-rsa';
import { ExtractJwt, Strategy } from 'passport-jwt';

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      secretOrKey: passportJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: `${process.env.AUTH0_DOMAIN}.well-known/jwks.json`,
      }),
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      audience: process.env.AUDIENCE,
      issuer: process.env.AUTH0_DOMAIN,
      algorithms: ['RS256'],
    });
  }

  validate(payload: JwtPayload): JwtPayload {
    return payload;
  }
}

GqlAuthGuard :

import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}

after doing this. I have done below changes to my mutations and queries

@Mutation(() => Appointment, { name: 'createAppointment' })
  @UseGuards(GqlAuthGuard)
  async createAppointment(
    @Args('createAppointmentInput') request: CreateAppointmentRequest,
  ): Promise<Appointment> {
    return this.appointmentsService.createAppointment(request);
  }

  /**
   * Get all appointments.
   * @returns An array of all appointments.
   */
  @UseGuards(GqlAuthGuard)
  @Query(() => [Appointment], { name: 'appointments' })
  async allAppointments(): Promise<Appointment[]> {
    return this.appointmentsService.getAllAppointments();
  }

Then when I passed the access token from Apollo Server Client I got below error

{
  "data": {},
  "errors": [
    {
      "message": "Unauthorized",
      "locations": [
        {
          "line": 58,
          "column": 3
        }
      ],
      "path": [
        "appointment"
      ],
      "extensions": {
        "code": "UNAUTHENTICATED",
        "stacktrace": [
          "UnauthorizedException: Unauthorized",
          "    at GqlAuthGuard.handleRequest (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/@nestjs/passport/dist/auth.guard.js:60:30)",
          "    at /home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/@nestjs/passport/dist/auth.guard.js:44:124",
          "    at /home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/@nestjs/passport/dist/auth.guard.js:83:24",
          "    at allFailed (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport/lib/middleware/authenticate.js:110:18)",
          "    at attempt (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport/lib/middleware/authenticate.js:183:28)",
          "    at JwtStrategy.strategy.fail (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport/lib/middleware/authenticate.js:305:9)",
          "    at /home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport-jwt/lib/strategy.js:106:33",
          "    at Object.module.exports [as verify] (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/jsonwebtoken/verify.js:70:12)",
          "    at Function.module.exports [as JwtVerifier] (/home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport-jwt/lib/verify_jwt.js:4:16)",
          "    at /home/sathyamolagodasolomoit/Documents/Projects/i4t-business-alpha/platforms/i4t-global-v4/api-aggregators/api-aggregator-business/node_modules/passport-jwt/lib/strategy.js:104:25"
        ],
        "originalError": {
          "statusCode": 401,
          "message": "Unauthorized"
        }
      }
    }
  ]
}

When I check the request from authguard token has been passed to backend correctly. Also when I check auth domain and audience also passing correctly to the strategy. Due to the lack of documentation and references I was not able to find the better solution for this. What can be the issue here, and If i’m doing this to GraphQL is there any other specific way to do this ?

Share


Load 6 more related questions


Show fewer related questions

0

Reset to default



Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *