#What is wrong with this access token guard code ?

1 messages · Page 1 of 1 (latest)

dull zinc
#

I am following nest.js official course on authentication and authorization. But I am using graphql code first approach instead of rest api.

This is the code for the access-token.guard.ts FROM the course intended for a REST API

import {
  CanActivate,
  ExecutionContext,
  Inject,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';

import jwtConfig from 'src/iam/config/jwt.config';
import { REQUEST_USER_KEY } from 'src/iam/iam.constant';

@Injectable()
export class AccessTokenGuard implements CanActivate {
  constructor(
    private readonly jwtService: JwtService,
    @Inject(jwtConfig.KEY)
    private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(
        token,
        this.jwtConfiguration,
      );
      request[REQUEST_USER_KEY] = payload;
      console.log(payload);
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }
  private extractTokenFromHeader(request: Request): string | undefined {
    const [_, token] = request.headers.authorization?.split('') ?? [];
    return token;
  }
}

the iam.constant.ts file includes the following

typescript export const REQUEST_USER_KEY = 'user';

#

this is my version of the code trying to use graphql

#
  CanActivate,
  ExecutionContext,
  Inject,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import { GqlExecutionContext } from '@nestjs/graphql';
import { JwtService } from '@nestjs/jwt';

import jwtConfig from 'src/iam/config/jwt.config';
import { REQUEST_USER_KEY } from 'src/iam/iam.constant';

@Injectable()
export class AccessTokenGuard implements CanActivate {
  constructor(
    private readonly jwtService: JwtService,
    @Inject(jwtConfig.KEY)
    private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const ctx = GqlExecutionContext.create(context);
    const { req } = ctx.getContext(); // Assuming context provides access to request object

    // Extract authorization header (adjust based on your context structure)
    const authorization = req?.headers?.authorization;

    if (!authorization) {
      throw new UnauthorizedException(
        'Invalid or missing authorization header',
      );
    }

    const token = this.extractTokenFromHeader(authorization);
    if (!token) {
      throw new UnauthorizedException('Invalid or missing token');
    }
    try {
      const payload = await this.jwtService.verifyAsync(
        token,
        this.jwtConfiguration,
      );
      authorization[REQUEST_USER_KEY] = payload; // Store in context data if applicable

      console.log(payload);
    } catch (error) {
      console.error('JWT verification error:', error);
      throw new UnauthorizedException('Invalid token');
    }
    return true;
  }
  private extractTokenFromHeader(authorization: string): string | undefined {
    const [_, token] = authorization?.split('') ?? [];
    return token;
  }
}
#

it seems that the token is not being transfered into the request as when testing with graphql playground I am getting the error "Invalid token".

#

this is the app.module.ts file. I am not sure about the graphql configuration though

#

import { AppController } from './app.controller';

import { AppService } from './app.service';

import { GraphQLModule } from '@nestjs/graphql';

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

import { join } from 'path';

import { ConfigModule } from '@nestjs/config';

import { UsersModule } from './users/users.module';

import * as Joi from 'joi';

import { PrismaModule } from './prisma/prisma.module';

import { PrismaService } from './prisma/prisma.service';

import { IamModule } from './iam/iam.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,

      validationSchema: Joi.object({
        DATABASE_URL: Joi.string().required(),
      }),
    }),

    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,

      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),

      context: ({ req }) => ({ headers: req.headers }),
    }),

    UsersModule,

    PrismaModule,

    IamModule,
  ],

  controllers: [AppController],

  providers: [AppService, PrismaService],
})
export class AppModule {}
surreal spruce
#

Hi