graphqlnestjspassport.jsexpress-sessionauth-guard

Login request is always 401 Unauthorized with AuthGuard


I have been following this tutorial and trying to convert it to GraphQL. I am trying to implement a NestJS + GraphQL + Passport + Express-Session solution but I am having problems with the AuthGuard. Sadly there is only little information on this available online. My AuthGuard looks like this

import { ExecutionContext, Injectable } from '@nestjs/common';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalGuard extends AuthGuard('local') {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const ctx = GqlExecutionContext.create(context);
    const { req } = ctx.getContext();
    const result = (await super.canActivate(
      new ExecutionContextHost([req]),
    )) as boolean;
    console.log(result);
    await super.logIn(req);
    return result;
  }
}

Unfortunately, I always receive a Unauthorized response when trying to do a login request. I think the problem comes from my super.canActivate call.


Solution

  • Update: This is my AuthGuard Implementation that finally worked. Overwriting getRequest and adding my input to the body fixes the problem.

    import { ExecutionContext, Injectable } from '@nestjs/common';
    import { GqlExecutionContext } from '@nestjs/graphql';
    import { AuthGuard } from '@nestjs/passport';
    @Injectable()
    export class LocalGuard extends AuthGuard('local') {
      async canActivate(context: ExecutionContext): Promise<boolean> {
        const result = (await super.canActivate(context)) as boolean;
        const ctx = GqlExecutionContext.create(context);
        const { req } = ctx.getContext();
        await super.logIn(req);
        return result;
      }
    
      getRequest(context: ExecutionContext) {
        const ctx = GqlExecutionContext.create(context);
        const gqlReq = ctx.getContext().req;
        if (gqlReq) {
          const { authCredentialsInput } = ctx.getArgs();
          gqlReq.body = authCredentialsInput;
          return gqlReq;
        }
      }
    }