I am creating an authentication system via UseGuards, but how can I inject dependencies into my guards? I'd like to do it in a global way, to avoid repeating code and every controller importing the injections.
I am using the mode of dependency inversion and injecting the classes, I am also making the classes only depend on implementations and interface rules...
My AuthServices
export class AuthServices implements IMiddlewareAuth {
constructor(
private readonly jwt: IJWTDecrypt,
private readonly authUserRepo: IAuthUserContract,
) {}
public async intercept(
req: IMiddlewareAuth.Attrs,
): Promise<IMiddlewareAuth.Return> {
const token = req.headers['Authorization'];
if (!token) {
new Fails('Access denied', 403);
}
const parts = token.split(' ');
if (parts.length !== 2) {
return new Fails('Anauthorized', 401);
}
const [scheme, access] = parts;
if (!/^Bearer$/i.test(scheme)) {
return new Fails('Anauthorized', 400);
}
const id = await this.jwt.decrypt(access);
if (!id) {
return new Fails('Anauthorized', 400);
}
const user = await this.authUserRepo.findById(id);
if (!user) {
return new Fails('Anauthorized', 400);
}
return user;
}
}
my Auth.Guards
@Injectable()
export class AuthorizationGuard implements CanActivate {
constructor(
@Inject('AuthServices')
private authServices: IMiddlewareAuth,
) {}
public async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user = await this.authServices.intercept(request);
if (user instanceof Fails) {
throw new HttpException(
{
statusCode: user.statusCode,
error: user.message,
},
user.statusCode,
);
}
request.user = {
email: user.email,
id: user.id,
name: user.name,
} as ISessionLogin;
return true;
}
}
my Auth.Module
@Module({
imports: [ConfigModule.forRoot(), TypeOrmModule.forFeature([UserEntity])],
providers: [
{
provide: AuthUserRepository,
useFactory: (dataSource: DataSource) => {
return new AuthUserRepository(
dataSource.getMongoRepository(UserEntity),
);
},
inject: [getDataSourceToken()],
},
{
provide: JsonWebToken,
useFactory: () => {
return new JsonWebToken();
},
},
{
provide: AuthServices,
useFactory: (
jwt: JsonWebToken,
authUserRepository: AuthUserRepository,
) => {
return new AuthServices(jwt, authUserRepository);
},
inject: [JsonWebToken, AuthUserRepository],
},
],
exports: [AuthServices],
})
export class AuthModule {}
Error
Use
@Inject(AuthService)
instead of@Inject('AuthService')
. The important distinction is that'AuthService'
is a string token that matchesAuthService.name
andAuthService
is a class reference. Also, make sure theCreateUsersModule
hasAuthModule
in itsimports
array