How to setup Google Oauth with passport for android and ios without duplicate endpoints in NestJs

793 Views Asked by At

So basically Im trying to setup Google OAuth for both ios and android but Im currently stuck, because the clientId and clientSecret is different for ios and android.

So when creating the Strategy class that extends PassportStrategy I have to define the client secret and client id inside the constructor. Is there a away to make this dynamic without having any code duplication?

GoogleStrategy

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor() {
    super({
      clientID: '', // dynamic for ios and android
      clientSecret: '',  // dynamic for ios and android
      callbackURL: '',
      scope: ['email', 'profile'],
    });
  }
  async validate(
    accessToken: string,
    refreshToken: string,
    profile: any,
    done: VerifyCallback,
  ): Promise<any> {
    const { name, emails, photos } = profile;
    done(null, profile);
  }
}

GoogleController

@Controller('google-auth')
export class GoogleAuthController {
  constructor(private readonly googleAuthService: GoogleAuthService) {}

  @Get('login')
  @UseGuards(AuthGuard('google'))
  login(@Param('platform') platform: string, @Req() req) {
    // Query params to switch between android and ios
    // e.g platform=android or platform=ios
    
    //But what now? The strategy get initiated inside the module
  }

  @Get('redirect')
  @UseGuards(AuthGuard('google'))
  redirect(@Req() req) {}

  @Get('status')
  status() {}

  @Get('logout')
  logout() {}
}

GoogleModule

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, GoogleStrategy], //How to use this strategy for both ios and android?
})
export class AppModule {}

The OAuth ClientId is different for iOS and Android: enter image description here

1

There are 1 best solutions below

0
On

We can do it by creating custom guard and use that in out controller.ts file

controller.ts file

  @UseGuards(FacebookGuard, AuthGuard(‘facebook’))

FacebookGuard.ts file

import { CanActivate, ExecutionContext } from ‘@nestjs/common’;
    import { ClientAppService } from ‘../clientApp/clientApp.service’;
    import { Injectable } from ‘@nestjs/common’;
    import { FacebookStrategy } from ‘../auth/facebook.strategy’;
    
    type Provider = {
      providerType: string;
      providerKey: string;
      providerSecret: string;
      callBackUrl: string;
    };
    
    @Injectable()
    export class FacebookGuard implements CanActivate {
      /**
       * Constructor
       * @param {ClientAppService} clientAppService
       */
      constructor(readonly clientAppService: ClientAppService) {}
    
      async canActivate(context: ExecutionContext): Promise<boolean> {
        const request = context.switchToHttp().getRequest();
        const data = await this.clientAppService.getProviderDetails(
          request.query.appKey,
          ‘facebook’,
        );
        const providerData = data.providerId as any;
         new FacebookStrategy(
          providerData.providerKey,
          providerData.providerSecret,
          providerData.callBackUrl + ‘/’ + request.query.appKey + 
           ‘/callback’,
        );
        return true;
      }
    }