cookiesgraphqlpassport.jsnestjsgraphql-subscriptions

How to implement auth guard for graphql subscriptions (passportjs + cookies)


How I can pass user to the request? Is there any possible way to implement something like SubscriptionAuthGuard?

without the subscription, everything works fine

Code:

GraphQLModule.forRoot({
      installSubscriptionHandlers: true,
      subscriptions: {
        'subscriptions-transport-ws': {
          onConnect: (connectionParams, webSocket) =>
            new Promise((resolve) => {
              passportInit(webSocket.upgradeReq, {} as any, () => {
                resolve(webSocket.upgradeReq);
              });
            }),
        },
      },
      context: ({ req }) => ({ req }),
    }),

Error:

TypeError: Cannot set property 'authInfo' of undefined

Solution

  • This worked for me, I'm using JWT and bearer tokens.

    GraphQL.module:

        'subscriptions-transport-ws': {
          path: '/graphql',
          onConnect: (connectionParams) => {
            return {
              req: {
                headers: { authorization:
                    connectionParams.Authorization ??
                    connectionParams.authorization,
                },
              },
            };
          },
        },
    

    Guard:

    
    @Injectable()
    export class JwtAuthGuard extends AuthGuard('jwt') {
      async canActivate(context: ExecutionContext): Promise<boolean> {
        try {
          return (await super.canActivate(context)) as boolean;
        } catch (e) {
          throw new AuthenticationError(generalErrorMessages.invalidToken);
        }
      }
    
      getRequest(context: ExecutionContext): Request {
        const ctx = GqlExecutionContext.create(context);
    
        return ctx.getContext().req;
      }
    }