+ +```ts +import { + AuthenticateFn, + AuthenticationBindings, + AUTHENTICATION_STRATEGY_NOT_FOUND, + USER_PROFILE_NOT_FOUND, +} from '@loopback/authentication'; +export class MySequence implements SequenceHandler { + constructor( + // - enable jwt auth - + // inject the auth action + @inject(AuthenticationBindings.AUTH_ACTION) + protected authenticateRequest: AuthenticateFn, + ) {} + + async handle(context: RequestContext) { + try { + const {request, response} = context; + const route = this.findRoute(request); + // - enable jwt auth - + // call authentication action + await this.authenticateRequest(request); + + const args = await this.parseParams(request, route); + const result = await this.invoke(route, args); + this.send(response, result); + } catch (error) { + // - enable jwt auth - + // improve the error check + if ( + error.code === AUTHENTICATION_STRATEGY_NOT_FOUND || + error.code === USER_PROFILE_NOT_FOUND + ) { + Object.assign(error, {statusCode: 401 /* Unauthorized */}); + } + this.reject(context, error); + } + } +} +``` + +
++ +```ts +import {AuthenticationComponent} from '@loopback/authentication'; +import { + JWTAuthenticationComponent, + SECURITY_SCHEME_SPEC, +} from '@loopback/extension-authentication-jwt'; + +export class TestApplication extends BootMixin( + ServiceMixin(RepositoryMixin(RestApplication)), +) { + constructor(options: ApplicationConfig = {}) { + super(options); + + // Set up the custom sequence + this.sequence(MySequence); + + // Set up default home page + this.static('/', path.join(__dirname, '../public')); + + // - enable jwt auth - + // Add security spec (Future work: refactor it to an enhancer) + this.addSecuritySpec(); + // Mount authentication system + this.component(AuthenticationComponent); + // Mount jwt component + this.component(JWTAuthenticationComponent); + // Bind datasource + this.dataSource(DbDataSource, UserServiceBindings.DATASOURCE_NAME); + + this.component(RestExplorerComponent); + this.projectRoot = __dirname; + // Customize @loopback/boot Booter Conventions here + this.bootOptions = {}; + } + + // - enable jwt auth - + // Currently there is an extra function to + // merge the security spec into the application. + // This will be improved with a coming enhancer. + // See section [Future Work](#future-work) + addSecuritySpec(): void { + this.api({ + openapi: '3.0.0', + info: { + title: 'test application', + version: '1.0.0', + }, + paths: {}, + components: {securitySchemes: SECURITY_SCHEME_SPEC}, + security: [ + { + // secure all endpoints with 'jwt' + jwt: [], + }, + ], + servers: [{url: '/'}], + }); + } +} +``` + +
+
+
+ ```ts
+ import {UserService} from '@loopback/authentication';
+ import {repository} from '@loopback/repository';
+ import {HttpErrors} from '@loopback/rest';
+ import {securityId, UserProfile} from '@loopback/security';
+ import {compare} from 'bcryptjs';
+ // User --> MyUser
+ import {MyUser} from '../models';
+ // UserRepository --> MyUserRepository
+ import {MyUserRepository} from '../repositories';
+
+ export type Credentials = {
+ email: string;
+ password: string;
+ };
+
+ // User --> MyUser
+ export class CustomUserService implements UserService