docs/site/decorators/Decorators_authenticate.md
Syntax:
@authenticate(strategyName)@authenticate(strategyName1, strategyName2) @authenticate({
strategy: strategyName,
options: {option1: 'value1', option2: 'value2'}
})
@authenticate({
strategy: strategyName1,
options: {option1: 'value1'}
}, {
strategy: strategyName2,
options: {option2: 'value2'}
})
To mark a controller method as needing an authenticated user, the decorator requires one or more strategies.
Here's an example using 'BasicStrategy': to authenticate user in function
whoAmI:
{% include code-caption.html content="src/controllers/who-am-i.controller.ts" %}
import {inject} from '@loopback/core';
import {securityId, SecurityBindings, UserProfile} from '@loopback/security';
import {authenticate} from '@loopback/authentication';
import {get} from '@loopback/rest';
export class WhoAmIController {
constructor(@inject(SecurityBindings.USER) private user: UserProfile) {}
@authenticate('BasicStrategy')
@get('/whoami')
whoAmI(): string {
return this.user[securityId];
}
}
To configure a default authentication for all methods within a class,
@authenticate can also be applied at the class level. In the code below,
whoAmI is protected with BasicStrategy even though there is no
@authenticate is present for the method itself. The configuration is inherited
from the class. The hello method does not require authentication as it's
skipped by @authenticate.skip.
@authenticate('BasicStrategy')
export class WhoAmIController {
constructor(@inject(SecurityBindings.USER) private user: UserProfile) {}
@get('/whoami')
whoAmI(): string {
return this.user[securityId];
}
@authenticate.skip()
@get('/hello')
hello(): string {
return 'Hello';
}
}
{% include note.html content="If only <b>some</b> of the controller methods are decorated with the <b>@authenticate</b> decorator, then the injection decorator for SecurityBindings.USER in the controller's constructor must be specified as <b>@inject(SecurityBindings.USER, {optional:true})</b> to avoid a binding error when an unauthenticated endpoint is accessed. Alternatively, do not inject SecurityBindings.USER in the controller <b>constructor</b>, but in the controller <b>methods</b> which are actually decorated with the <b>@authenticate</b> decorator. See Method Injection, Constructor Injection and Optional Dependencies for details. " %}
For more information on authentication with LoopBack, visit here.
@authenticate() can takes in more than one strategy. For example:
import {inject} from '@loopback/core';
import {securityId, SecurityBindings, UserProfile} from '@loopback/security';
import {authenticate} from '@loopback/authentication';
import {get} from '@loopback/rest';
export class WhoAmIController {
constructor(@inject(SecurityBindings.USER) private user: UserProfile) {}
@authenticate('BasicStrategy', 'JWTStrategy')
@get('/whoami')
whoAmI(): string {
return this.user[securityId];
}
}
The logic on how the strategies are executed is similar to how passport.js does it:
{% include note.html content="It is not feasible to use multiple strategies that redirect (e.g. OAuth login redirects) since the first redirect will halt the execution chain. " %}