@narando/nest-auth
v0.3.0
Published
Authenticate and authorize incoming requests.
Downloads
9
Keywords
Readme
@narando/nest-auth
Authenticate and authorize incoming requests.
Getting Started
Requirements
- NestJS 7.1.3+
Installation
npm i @narando/nest-auth
Configuration
With the package installed, import the AuthModule
into the root AppModule
.
import { AuthModule } from "@narando/nest-auth";
@Module({
imports: [
AuthModule.register({
enableGlobally: true,
jwt: {
publicKey: "1337",
algorithm: "HS256",
},
}),
],
providers: [APIService],
})
export class AppModule {}
You can also use AuthModule.registerAsync()
to dynamically load configuration.
Usage
There are two ways to enable the checks. You can enable them globally through
the enableGlobally
flag that can be set on the module import. You can also
enable them per controller/route by using the @Auth()
decorator.
Authentication
For every incoming request the package will check the Authorization
header for
a bearer token and will validate this token as a JWT against the credentials
supplied during module import.
If the token is invalid or expired a 401 Unauthorized
is returned to the user.
If the token is valid, the payload will be restructured and made available to
the controller at req.user
. You can use the @ReqUser
decorator to inject it
into your controller function:
import { ReqUser, AuthUser } from "@narando/nest-auth";
@Controller("cats")
export class CatController {
findAllForUser(@ReqUser() user: AuthUser) {
return this.catService.findAllForUser(user.id);
}
}
Authorization
Activities take the form service:scope:method:item
, eg.:
api:articles:get:list
. A Permission is an Activity that is linked to an user
and contains additional information:
// Permission
{
// Name of Activity
name: "service:scope:method:item",
// Wether this permission only applies to objects that
// the user owns/has control of.
onlyAssociated: true,
}
These permissions are included in the JWT and the authentication middleware will automatically parse them and add them to the request object.
By default the package will not verify that the user is authorized to perform any actions.
You can enable this on a per-controller or per-route basis. Use the @Auth()
decorator to specify the required permission to access the route.
You can specify the decorator on the controller to set defaults and then override them on a per-route basis.
import { Auth } from "@narando/nest-auth";
@Controller("cats")
@Auth({
service: "animal-shelter",
scope: "cat",
})
export class CatController {
@Get()
@Auth({
method: "get",
item: "list",
})
findAll() {
return this.cats;
}
}
Now every request going to the findAll
route need to have the permission
animal-shelter:cat:get:list
, otherwise the request will be aborted with 403 Forbidden
.
Association-based checks
In many cases we'll not just check if a user is allowed to perform the action itself but if he is allowed to perform the action on this specific resource.
This is achieved by implementing an async function called isAssociated()
on the service which should check the association. For example if we want to validate if the user is associated with an BillingEntity
we would implement the isAssociated()
function in the BillingEntitiesService
.
The isAssociated()
function takes an object containing user
and reqParams
as an input and returns a boolean.
import { AuthAssociatedCheck, IsAssociatedArguments } from "@narando/nest-auth";
@Injectable()
export class CatService implements AuthAssociatedCheck {
async isAssociated({
user,
reqParams,
}: IsAssociatedArguments): Promise<boolean> {
// determine if associated or not
return false;
}
}
To enable these checks we'll need to pass the service containing the isAssociated()
function in the @Auth()
decorator like below:
@Auth({
method: "read",
item: "self",
associationCheckService: CatService
})
Disabling authentication
It is possible to explicitly disable authentication on a route (or controller) by setting the disable: true
flag.
import { Auth } from "@narando/nest-auth";
@Auth({
disable: true
})