Я хочу реализовать стратегию паспорта google и facebook, используя несколько ключей для разных приложений, например получить clientID или что-то в параметрах req и выбрать google clientID и clientSecret из БД на основе заданного параметра, т.е. пользователи одного приложения могут аутентифицироваться с использованием определенного clientID и clientSecret , хочу реализовать что-то подобное, но не знаю, как это сделать в NestJS, так как я новичок в NestJS. https://medium.com/passportjs/authenticate-using-strategy-instances-49e58d96ec8c
// GoogleStrategy code
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor() {
super({
clientID: '', // dynamic key from multiple type of application
clientSecret: '', // dynamic key from multiple type of application
callbackURL: '', // url from user request or hardcoded
scope: ['email', 'profile'], //hardcoded or data from request
});
}
async validate(
accessToken: string,
refreshToken: string,
profile: any,
done: VerifyCallback,
): Promise<any> {
const { name, emails, photos } = profile;
done(null, profile);
}
}
// Goole Controler
@Controller('google-auth')
export class GoogleAuthController {
constructor(private readonly googleAuthService: GoogleAuthService) {}
@Get('login')
@UseGuards(AuthGuard('google'))
login(@Param('appID') appID: string, @Req() req) {
// Query params to switch between two app type
// e.g app1ID=123132323 or app2ID=2332323
//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 with multiple
// clientID and clientSecret on base of a
// param
})
export class AppModule {}
Мы можем сделать это, создав собственную защиту и используя ее в файле controller.ts.
файл controller.ts
@UseGuards(FacebookGuard, AuthGuard('facebook'))
Файл FacebookGuard.ts
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;
}
}