nestjs / passport

Passport module for Nest framework (node.js) 🔑

Home Page:https://nestjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Consider creating a fastify version with the new fastify-passport port

squareloop1 opened this issue · comments

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Passport with all of its strategies is currently not usable with fastify. Lately the team at fastify made progress on porting passport to fastify (https://github.com/fastify/fastify-passport).

Expected behavior

A fastify-passport version for NestJS using the new port from fastify would be great. Maybe it could even be incorporated into this package with a conditional check of the underlying used platform (express / fastify). The API changes should be minimal (see https://github.com/fastify/fastify-passport#differences-from-passportjs).

What is the motivation / use case for changing the behavior?

Many are using fastify instead of express for better performance and building cutting edge applications thanks to NestJS' platform agnosticism. Almost every middleware driven package on express has some kind of equivalent for fastify already. Passport was sadly still something that was missing in the fastify ecosystem. With the new fastify-passport we could bring that missing part to the NestJS ecosystem.

image

Current status: Alpha. Pre-any-release.

When it becomes stable, we'll definitely create a wrapper library (or even integrate it with the existing one)

The stable version has been released. Could you wrap it up?

Sadly v0.1.0 of fastify-passport is not a stable release and still the alpha until more feedback and confidence is coming in probably.

FYI: I forked @nestjs/passport and made a PoC of how it could work with fastify-passport: https://github.com/squareloop1/passport. I am running it in one of my projects currently and it is working good so far.

FYI: I forked @nestjs/passport and made a PoC of how it could work with fastify-passport: https://github.com/squareloop1/passport. I am running it in one of my projects currently and it is working good so far.

Thank you for sharing it.

Can we reopen this? it's now in beta. I don't see it getting out of beta until more folks are using it, so it's a chicken and egg situation. Would be nice to have as optional

I think this can actually be reopened since @fastify/passport is on version 2.4.0

Hi, I'm not sure if it works for all cases, but for me it works:

  1. From @squareloop1 example took
const createPassportContext = (request, response) => async (type, options, callback) => {
  return new Promise(async (resolve, reject) => {
    try {
      return await request.passport.authenticate(type, options, (request, response, err, user, info, status) => {
        try {
          request.authInfo = info;
          return resolve(callback(err, user, info, status));
        } catch (err) {
          reject(err);
        }
      })(request, response);
    } catch (error) {
      reject(error);
    }
  });
}
  1. Wrote (don't look at types)
export abstract class PassportSerializer {
  abstract registerUserSerializer(user: unknown, request: any): Promise<any>;
  abstract registerUserDeserializer(user: unknown, request: any): Promise<any>;

  constructor() {
    const passportInstance = this.getPassportInstance();
    passportInstance.registerUserSerializer((user: any, req: any) =>
      this.registerUserSerializer(user, req)
    );

    passportInstance.registerUserDeserializer((id: string, req: any) =>
      this.registerUserDeserializer(id, req)
    );
  }

  getPassportInstance() {
    return passport;
  }
}
  1. There is a MixinAuthGuard returned from createAuthGuard function in the package. I changed the logic of 1 method:
async logIn<TRequest extends { logIn: Function } = any>(request: TRequest): Promise<void> {
      const user = request[(this.options.property || defaultOptions.property) as keyof TRequest];
      // await new Promise<void>((resolve, reject) =>
      //   request.logIn(user, this.options, (err: any) => (err ? reject(err) : resolve()))
      // ); old commented
      await request.logIn(user);
    }