3

I'm new in LoopBack v4 and I'm trying to send an authorization key with every request. I used Swagger before, and I used to add the api key, after clicking on the "Authorize" button to the right. To avoid error due my inexperience, I've started with a fresh app of "Todo List" example. I tried (with not success) to follow what this post suggests: Nodejs Loopback 4 add bearer token config into swagger explorer

What I did is modify the file src/index.ts with this code:

export async function main(options: ApplicationConfig = {}) {
  const spec: OpenApiSpec = {
    openapi: '3.0.0',
    info: {
      title: 'LoopBack Application v2',
      version: '1.0.2',
    },
    paths: {
    },
    securityDefinitions: [
      {
        api_key: [
          {
            type: 'apiKey',
            name: 'api_key',
            in: 'header'
          }
        ]
      },
    ],
  };

  const app = new TodoListApplication(options);
  app.api(spec);

  await app.boot();
  await app.start();

  const url = app.restServer.url;
  console.log(`Server is running at ${url}`);
  return app;
}

Basically, I added this line: app.api(spec); and the config securityDefinitions. The spec constant changes the title and version, but I still cannot see the "Authorize" button. For sure, I'm missing something or doing something wrong.

Any help is appreciated! Thanks!

3 Answers3

6

Finally, I added the "Authorize" button and send the api_key in the header, with this configuration:

  const spec: OpenApiSpec = {
    openapi: '3.0.0',
    info: {
      title: 'LoopBack Application v2',
      version: '1.0.2',
    },
    paths: {},
    security: [
      {
        api_key: ['api_key'],
      },
    ],
    components: {
        securitySchemes: {
          api_key: {
            type: 'apiKey',
            name: 'api_key',
            in: 'header'
          }
        }
    },
  };
0

create a security spec file in your file system like below

import {ReferenceObject, SecuritySchemeObject} from '@loopback/openapi-v3';

export const SECURITY_SPEC = [{bearerAuth: []}];
export type SecuritySchemeObjects = {
  [securityScheme: string]: SecuritySchemeObject | ReferenceObject;
};
export const SECURITY_SCHEME_SPEC: SecuritySchemeObjects = {
  bearerAuth: {
    type: 'http',
    scheme: 'bearer',
    bearerFormat: 'JWT',
  },
};

add below code in application.ts file in XXXX application class below super(options) and import SECURITY_SCHEME_SPEC, SECURITY_SPEC from the security spec file.

 this.api({
      openapi: '3.0.0',
      info: {title: "package or prject name", version: '1.0'},
      paths: {},
      components: {securitySchemes: SECURITY_SCHEME_SPEC},
      servers: [{url: '/'}],
      security: SECURITY_SPEC
    });

Referance loopback link

Muralikrishna
  • 1,044
  • 10
  • 17
0

For "@loopback/core": "^4.0.3" this can be achieved as describes in OAS Enhancer Service as Extension Point.

  1. Create a new OASEnhancer class i.e. JwtAuthSpecEnhancer in my-spec.ts
import { injectable } from '@loopback/core';
import {
  mergeOpenAPISpec,
  mergeSecuritySchemeToSpec,
  asSpecEnhancer,
  OASEnhancer,
  OpenApiSpec,
} from '@loopback/rest';

@injectable(asSpecEnhancer)
export class JwtAuthSpecEnhancer implements OASEnhancer {
  name = 'YOUR_SCHEME_NAME';

  modifySpec(spec: OpenApiSpec): OpenApiSpec {
    const securitySchemeSpec = mergeSecuritySchemeToSpec(spec, 'ANY_NAME', {
      type: 'http',
      scheme: 'bearer',
      bearerFormat: 'JWT'
    });
    const securitySpec = mergeOpenAPISpec(securitySchemeSpec, {
      security: [
        {
          ANY_NAME: [],
        },
      ]
    });
    return securitySpec;
  }
}
  1. Bind it to application.ts
import {ApplicationConfig, createBindingFromClass} from '@loopback/core';
import {AuthenticationComponent} from '@loopback/authentication';
import {JwtAuthSpecEnhancer} from './my-spec.ts'
export class MyRestApplication extends BootMixin(
  ServiceMixin(RepositoryMixin(RestApplication)),
) {

...

this.component(AuthenticationComponent);
this.add(createBindingFromClass(JwtAuthSpecEnhancer ));

...

this.projectRoot = __dirname;
    // Customize @loopback/boot Booter Conventions here
    this.bootOptions = {
      controllers: {
        // Customize ControllerBooter Conventions here
        dirs: ['controllers'],
        extensions: ['.controller.js'],
        nested: true,
      },
    };
  }
}

Done!.

Alternatively, refers to Swagger doc for ApiKey type auth. For example, the OAS Enhancer can be configured to use access_token in the header as follows:

...
modifySpec(spec: OpenApiSpec): OpenApiSpec {
    const securitySchemeSpec = mergeSecuritySchemeToSpec(spec, 'token', {
      type: 'apiKey',
      name: 'access_token',
      in: 'header'
    });
    const securitySpec = mergeOpenAPISpec(securitySchemeSpec, {
      security: [
        {
          token: ['access_token'],
        },
      ]
    });
    return securitySpec;
  }
...

Note that Loopback 4 supports SecuritySchemeType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect'

hadifikri
  • 434
  • 3
  • 10