@petbee/nestjs-petbee-auth v0.0.19
Petbee Authentication Module for NestJS
This authentication module provides a flexible and configurable approach to integrating JWT-based authentication into your NestJS applications. It supports both static and dynamic configuration and allows for the optional integration of a custom user data fetching service.
Features
- JWT Strategy integration
- Custom user data fetching
- Static and dynamic module configuration
- Extendable to various authentication scenarios
Installation
npm install @petbee/nestjs-petbee-auth
# or
yarn add @petbee/nestjs-petbee-auth
Make sure you have NestJS installed in your project. If not, install them:
npm install @nestjs/common @nestjs/core
# or
yarn add @nestjs/common @nestjs/core
Usage
Static Configuration
Import the AuthModule into your application module and use the register method for static configuration:
// app.module.ts
import { Module } from '@nestjs/common'
import { AuthModule } from '@petbee/nestjs-petbee-auth'
@Module({
imports: [
AuthModule.register({
authConfig: {
domain: 'AUTH_PROVIDER_ISSUER_URL',
},
}),
// ... other imports
],
})
export class AppModule {}
Dynamic/Asynchronous Configuration
For more complex scenarios where configuration might depend on asynchronous operations, use the registerAsync method:
// app.module.ts
import { Module } from '@nestjs/common'
import { AuthModule } from '@petbee/nestjs-petbee-auth'
import { ConfigService } from './config/config.service' // Assuming you have a ConfigService
@Module({
imports: [
AuthModule.registerAsync({
imports: [ConfigModule], // Import the module that provides ConfigService
useFactory: async (configService: ConfigService) => ({
authConfig: {
domain: configService.get<string>('auth.issuerUrl'),
},
}),
userDataFetcher: {
useClass: MockUserDataFetcher,
}, // optional
inject: [ConfigService], // Inject ConfigService
}),
// ... other imports
],
})
export class AppModule {}
You could also use as a factory:
// app.module.ts
import { Module } from '@nestjs/common'
import { AuthModule } from '@petbee/nestjs-petbee-auth'
import { ConfigService } from './config/config.service' // Assuming you have a ConfigService
import { UserService } from './user/user.service' // Assuming you have a UserService
import { UserModule } from './user/user.module' // Assuming you have a UserModule and it's not global
@Module({
controllers: [AppController],
imports: [
AuthModule.registerAsync({
imports: [UserModule],
useFactory: () => ({
authConfig: {
domain: 'example.auth.com',
},
}),
userDataFetcher: {
useFactory: (userService: UserService) => new MockInjectUserDataFetcher(userService),
inject: [UserService],
},
}),
],
providers: [AppService],
})
export class AppModuleAsyncWithDataFetcherInject {}
Custom UserDataFetcher
To add additional user data to the JWT payload, implement a custom UserDataFetcher:
// custom-user-data-fetcher.service.ts
import { Injectable } from '@nestjs/common'
import { UserDataFetcher, UserDataFetcherInput } from '@petbee/nestjs-petbee-auth'
@Injectable()
export class CustomUserDataFetcher implements UserDataFetcher {
async fetchAdditionalData(input: UserDataFetcherInput): Promise<User> {
// Implement your logic to fetch additional user data
return additionalUserData as User
}
}
Configuration Options
Configure the AuthModule
with the following options defined in the IAuthModuleOptions
interface:
defaultStrategy
(string | string[]): Specifies the default strategy or strategies to be used. Default is 'jwt'.session
(boolean): Determines whether to use sessions. Defaults tofalse
.authConfig
(IAuthConfig
): Configuration specific to authentication. It includes:domain
(string): The domain against which authentication will be performed.algorithms
(string | string[]): The algorithms to be used for authentication. Default is 'RS256'.
The IAuthConfig
interface is used to specify detailed authentication-related configurations, and IAuthModuleOptions
interface allows for broader module configuration, including the option to add any additional key-value pairs as needed.
Dynamic/Asynchronous Configuration
You can configure the AuthModule
asynchronously using the AuthModuleAsyncOptions
interface, which extends from ModuleMetadata
and allows for the following:
useExisting
(Type<AuthOptionsFactory>
): Reuse an existing factory for creating auth options.useClass
(Type<AuthOptionsFactory>
): Specify a class that will provide the auth options.useFactory
(Function): A factory function that returns the auth options (either synchronously or asynchronously).inject
(any[]): Dependencies that the factory function requires.userDataFetcher
(UserDataFetcher
): Optional service to fetch additional user data.enhanceUserCtx
(Boolean
): Optional option to enhace the user context with data from default external API. Only works if no userDataFetcher service was provided.
Guards
AuthenticationGuard
AuthenticationGuard
is an extension of NestJS's built-in AuthGuard that uses the 'jwt' strategy. It incorporates additional logic to handle public routes in an application that uses JWT authentication globally.
Usage
To use AuthenticationGuard
globally in your NestJS application:
import { Reflector } from '@nestjs/core'
import { AuthenticationGuard } from '@petbee/nestjs-petbee-auth'
// In your main.ts or a similar entry file
const reflector = new Reflector()
app.useGlobalGuards(new AuthenticationGuard(reflector))
This will apply JWT authentication to all routes in your application, except those explicitly marked as public.
Decorators
@Authentication Decorator
The @Authentication decorator applies the AuthenticationGuard to a specific controller or route. It's used to enforce JWT authentication on private routes when the guard is not set globally.
Usage
To make a particular route or entire controller require authentication:
import { Authentication } from '@petbee/nestjs-petbee-auth'
@Controller()
@Authentication() // Apply to all routes in the controller
export class SomeController {
@Get()
findSomething() {
// This route requires authentication
}
@Post()
@Authentication() // Apply to a specific route
createSomething() {
// This route also requires authentication
}
}
@Public Decorator
The @IsPublic decorator is used to mark specific routes or entire controllers as public, bypassing the JWT authentication even if it's set globally.
Usage
To make a particular route or entire controller public:
import { Public } from '@petbee/nestjs-petbee-auth'
@Controller()
@Public() // Apply to all routes in the controller
export class PublicController {
@Get()
findSomething() {
// This route is public
}
@Post()
@Public() // Apply to a specific route
createSomething() {
// This route is also public
}
}
@Roles
The @Roles decorator is used to mark specific routes or entire controllers as allowed only to users with specific roles passed as argument. The argument can be an string or array of strings.
Usage
To make a particular route or entire controller restricted to specic role:
- Remember to set the
@Authentication
decorator if you don't have configured the global authentication guard. - It's important to say that Class and Method decorators roles will be merged, so if the Class allow access to
clinics
and then the method decorator allows access tosome-other-role
to that specific method bothclinics
andsome-other-role
will be allowed.
import { Public } from '@petbee/nestjs-petbee-auth'
@Controller()
@Roles(['clinics']) // Apply to all routes in the controller
@Authentication() // Only if you not set authentication guard globally
export class PublicController {
@Get()
findSomething() {
// This route is public
}
@Post()
@Roles(['some-other-role', 'some-another-role']) // Apply to a specific route
@Authentication() // Only if you not set authentication guard globally
createSomething() {
// This route is also public
}
}
@OnlyAdmin Decorator
The @OnlyAdmin decorator is used to mark specific routes or entire controllers as allowed only to users with admin role. We check for isAdmin prop on user ctx or if the roles prop has admin string.
Usage
To make a particular route or entire controller admin only:
- Remember to set the
@Authentication
decorator if you don't have configured the global authentication guard. - The
@OnlyAdmin
adds aRoles['admin]
behind the scenes, so the merge with Class and Method will happen as explained in @Roles decorator.
import { Public } from '@petbee/nestjs-petbee-auth'
@Controller()
@OnlyAdmin() // Apply to all routes in the controller
@Authentication() // Only if you not set authentication guard globally
export class PublicController {
@Get()
findSomething() {
// This route is public
}
@Post()
@OnlyAdmin() // Apply to a specific route
@Authentication() // Only if you not set authentication guard globally
createSomething() {
// This route is also public
}
}
@Clinics Decorator
The @Clinics decorator is used to mark specific routes or entire controllers as allowed only to users with clinics or admin role. We check if the roles has clinics on user ctx.
Usage
To make a particular route or entire controller admin only:
- Remember to set the
@Authentication
decorator if you don't have configured the global authentication guard. - The
@Clinics
adds aRoles['clinics', 'clinic']
behind the scenes, so the merge with Class and Method will happen as explained in @Roles decorator.
import { Public } from '@petbee/nestjs-petbee-auth'
@Controller()
@Clinics() // Apply to all routes in the controller
@Authentication() // Only if you not set authentication guard globally
export class PublicController {
@Get()
findSomething() {
// This route is public
}
@Post()
@Clinics() // Apply to a specific route
@Authentication() // Only if you not set authentication guard globally
createSomething() {
// This route is also public
}
}