https://github.com/flowcore-io/library-nestjs-oidc-protect-ts
A NestJS OpenID Connect library that can validate a token and protect routes with Auth and Role Guards. This is build to use the @flowcore/microservice library for configuration.
https://github.com/flowcore-io/library-nestjs-oidc-protect-ts
Last synced: 4 months ago
JSON representation
A NestJS OpenID Connect library that can validate a token and protect routes with Auth and Role Guards. This is build to use the @flowcore/microservice library for configuration.
- Host: GitHub
- URL: https://github.com/flowcore-io/library-nestjs-oidc-protect-ts
- Owner: flowcore-io
- License: mit
- Created: 2022-12-30T11:33:51.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-12-09T10:42:05.000Z (over 1 year ago)
- Last Synced: 2025-09-30T13:49:15.694Z (9 months ago)
- Language: TypeScript
- Homepage:
- Size: 280 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README

# NestJS Oidc-Protect
A NestJS OpenID Connect library that can validate a token and protect routes with Auth and Role Guards. This is build to
use the [@flowcore/microservice](https://www.npmjs.com/package/@flowcore/microservice) library for configuration.
## Installation
install with npm:
```bash
npm install @flowcore/nestjs-oidc-protect @flowcore/microservice
```
or yarn:
```bash
yarn add @flowcore/nestjs-oidc-protect @flowcore/microservice
```
> If you are using GraphQL, you also need to install the `@nestjs/graphql` package.
## Configuration
Import the OidcProtectModule into your NestJS application and configure it with your Keycloak server's details:
```typescript
import { OidcProtectModuleBuilder, OidcProtectConfigurationSchema } from '@flowcore/nestjs-oidc-protect';
import { ConfigModule, ConfigFactory } from '@flowcore/microservice';
import { AuthGuardBuilder } from "./auth-guard.builder";
const config = ConfigModule.forRoot(
new ConfigFactory()
// ...other configuration schemas
.withSchema(OidcProtectConfigurationSchema)
// ...other configuration schemas,
);
@Module({
imports: [
config,
// ...other modules
new OidcProtectModuleBuilder().withConfig(config).build(),
],
providers: [
...new AuthGuardBuilder()
.usingRoleGuard()
.usingResourceGuard()
.build(),
],
})
export class AppModule {
}
```
This can then be configured in a service with the following environment variables
| Environment Variable | Description | Type | Default Value | Required |
|----------------------|------------------------------------------------------------------------------------------------|:--------:|---------------|:--------:|
| OIDC_WELLKNOWN_URL | The wellknown configuration endpoint value for the authentication server | `url` | | X |
| OIDC_RESOURCE_ID | The resource ID configured for this service, this is required for `resource_access` validation | `string` | | |
## Usage
The `AuthGuard` is global and will protect all routes by default. You can use the `@Public()` decorator to exclude
routes from the AuthGuard.
```typescript
import { Public } from '@flowcore/nestjs-oidc-protect';
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@Public()
getHello(): string {
return 'Hello World!';
}
}
```
You can also use the `@RealmRoles()` or `@ResourceRoles` decorators to protect routes with a RoleGuard.
The `@RealmRoles()` and `@ResourceRoles()` decorators accepts a list of
roles. If the user has one of the roles, the route will be accessible.
```typescript
import { Roles } from '@flowcore/nestjs-oidc-protect';
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@RealmRoles(['admin', 'write'])
getHello(): string {
return 'Hello World!';
}
@ResourceRoles(['read', 'write'])
getHello(): string {
return 'Hello World!';
}
}
```
Resource will be swapped out for the `resourceId` configured in the `OidcProtectModule`. If no resourceId is configured,
the `resource_access` claim will never go through and will fail the guard.
> The `resource` roles refer to the `resource_access` field in the token. The `realm` roles refer to the `realm_access`
> field in the token.
> It is not possible to use `@RealmRoles()` and `@ResourceRoles()` on the same route.
For public endpoints like `/health` or `/metrics` you can use the built-in public endpoints are used to keep these paths
open. If you want to override these defaults or disable them, you can do so by configuring the `OidcProtectModule` using
the `OidcProtectModuleBuilder`:
```typescript
@Module({
imports: [
config,
// ...other modules
new OidcProtectModuleBuilder()
.withConfig(config)
.noPublicEndpoints() // for disabling the built-in public endpoints
.overridePublicEndpoints(
[
'/health',
'/metrics',
'/healthz',
],
)
.build(),
],
// ... other provider, controllers etc.
})
export class AppModule {
}
```
to optimize the performance you can specify a cache using the `withCache()` method on the `OidcProtectModuleBuilder`:
```typescript
import { CACHE_MANAGER, CacheModule } from "@nestjs/cache-manager";
const cacheModule = CacheModule.register();
@Module({
imports: [
config,
// ...other modules
cacheModule,
new OidcProtectModuleBuilder()
.withConfig(config)
.withCache(cacheModule, CACHE_MANAGER)
.build(),
],
// ... other provider, controllers etc.
})
export class AppModule {
}
```
> This supports the same cache managers as the `@nestjs/cache-manager` module.
To get access to the user information in the request, you can use the `@AuthenticatedUser()` decorator:
```typescript
import { AuthenticatedUser } from '@flowcore/nestjs-oidc-protect';
import { Roles } from '@flowcore/nestjs-oidc-protect';
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@RealmRoles(['admin', 'write'])
getHello(@AuthenticatedUser() user: any /* change to match your token */): string {
return 'Hello World!';
}
}
```
> An options object can be passed to the `@AuthenticatedUser()` decorator to specify the property name of the user and if it should be optional.
> The default options are `{ required: true, storedIn: "authenticatedUser" }`.
> This also works with @Resolvers() in GraphQL.
We hope you find this library useful in your NestJS projects!
## Development
```bash
yarn install
```
or with npm:
```bash
npm install
```