1
votes

Strongloop / Loopback 4: comment désactiver l'authentification pour le composant Explorer sur REST?

J'ai suivi et configuré via @loopback / authentification Mais l'authentification est ajoutée à sequence.ts pour tous les appels. Je ne parviens pas à ignorer l'authentification pour le composant Explorer

Mon dépôt open source: opencommerce / serveur de questionnaires

Détails:

Unhandled error in GET /: 500 Error: The key controller.current.ctor was not bound to any value.
at QuestionnaireApplication.getBinding (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/context.js:225:15)
at RestServer.getBinding (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/context.js:221:33)
at RequestContext.getBinding (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/context.js:221:33)
at RequestContext.getValueOrPromise (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/context.js:260:30)
at resolution_session_1.ResolutionSession.runWithInjection.s (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolver.js:73:24)
at value_promise_1.tryWithFinally (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolution-session.js:89:53)
at Object.tryWithFinally (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/value-promise.js:162:18)
at Function.runWithInjection (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolution-session.js:89:32)
at resolve (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolver.js:66:59)
at value_promise_1.resolveList (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolver.js:144:16)
at Object.resolveList (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/value-promise.js:135:32)
at resolveInjectedArguments (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolver.js:128:28)
at Object.instantiateClass (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolver.js:37:27)
at Binding._getValue (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/binding.js:338:50)
at resolution_session_1.ResolutionSession.runWithBinding.s (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/binding.js:189:90)
at value_promise_1.tryWithFinally (/opt/lampp7.2/htdocs/opencommerce/questionnaire-server/node_modules/@loopback/context/dist/src/resolution-session.js:69:53)


    import {inject} from '@loopback/context';
      import {
        FindRoute,
        InvokeMethod,
        ParseParams,
        Reject,
        RequestContext,
        RestBindings,
        Send,
        SequenceHandler,
      } from '@loopback/rest';
      import {AuthenticationBindings, AuthenticateFn} from '@loopback/authentication';

      const SequenceActions = RestBindings.SequenceActions;

      export class MySequence implements SequenceHandler {
        constructor(
          @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
          @inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
          @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
          @inject(SequenceActions.SEND) public send: Send,
          @inject(SequenceActions.REJECT) public reject: Reject,
          @inject(AuthenticationBindings.AUTH_ACTION)
          protected authenticateRequest: AuthenticateFn,
        ) {}

        async handle(context: RequestContext) {
          try {
            const {request, response} = context;
            const route = this.findRoute(request);

            // This is the important line added to the default sequence implementation
            await this.authenticateRequest(request);

            // Authentication successful, proceed to invoke controller
            const args = await this.parseParams(request, route);
            const result = await this.invoke(route, args);
            this.send(response, result);
          } catch (err) {
            this.reject(context, err);
          }
        }
      }

Erreur lors de l'accès à / .



    import {BootMixin} from '@loopback/boot';
      import {ApplicationConfig} from '@loopback/core';
      import {
        RestExplorerBindings,
        RestExplorerComponent,
      } from '@loopback/rest-explorer';
      import {RepositoryMixin} from '@loopback/repository';
      import {RestApplication} from '@loopback/rest';
      import {ServiceMixin} from '@loopback/service-proxy';
      import {
        AuthenticationComponent,
        AuthenticationBindings,
      } from '@loopback/authentication';
      import {MyAuthStrategyProvider} from './providers';
      import * as path from 'path';
      import {MySequence} from './sequence';

      export class QuestionnaireApplication 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'));

          // Customize @loopback/rest-explorer configuration here
          this.bind(RestExplorerBindings.CONFIG).to({
            path: '/explorer',
          });
          this.component(RestExplorerComponent);

          this.projectRoot = __dirname;

          this.component(AuthenticationComponent);
          this.bind(AuthenticationBindings.STRATEGY).toProvider(
              MyAuthStrategyProvider,
          );

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


6 commentaires

Normalement, vous ne devriez pas avoir de problèmes si vous ne mettez pas la stratégie de décorateur sur votre point de terminaison. Pourriez-vous poster le code de votre manette?


Bien sûr, je vais ajouter tout le code aujourd'hui.


@angelwally j'ai ajouté mon repo github. C'est le projet généré avec lb4 .


Je ne vois aucun contrôleur avec le chemin /. Avez-vous une?


github.com/opencommerce/questionnaire-server/blob/master/ src‌ /… this.component (RestExplorerComponent); Il gère le chemin / et rend une interface utilisateur swagger pour l'API. Mais quand j'ajoute l'authentification comme dans github.com/opencommerce/ questionnaire-server / blob / master / src‌ /… attendez this.authenticateRequest (request); entraîne une exception comme ci-dessus.


Salut @angelwally J'ai mis à jour la question avec tous les détails. S'il-vous-plaît évaluez,


3 Réponses :


1
votes

Un problème que vous pouvez avoir est que vous liez les valeurs après avoir défini votre séquence. Ensuite, les liaisons n'existent pas lorsque Loopback tente de les résoudre. Vous devriez mettre quelque chose de plus comme ceci:

      this.bind(RestExplorerBindings.CONFIG).to({
        path: '/explorer',
      });
      this.component(RestExplorerComponent);

      this.component(AuthenticationComponent);
      this.bind(AuthenticationBindings.STRATEGY).toProvider(
          MyAuthStrategyProvider,
      );

      this.sequence(MySequence);


4 commentaires

Merci mais cela n'a pas fonctionné. Est-ce que je peux essayer autre chose?


J'ai essayé votre code, mais il n'y a pas d'itinéraire pour / . Celui dont vous parlez est / explorer .


Merci pour vos efforts. Mettez simplement en commentaire la ligne attendez this.authenticateRequest (request); de sequence.ts et vous verrez que / route rend un défaut page html ie this.static ('/', path.join (__ dirname, '../../public')); dans application.ts .


Pouvez-vous essayer ci-dessus?



1
votes

Votre séquence personnalisée n'ignore pas l'authentification pour la route statique / . Il peut être ignoré comme suit:

import {inject} from '@loopback/context';
import {
  FindRoute,
  InvokeMethod,
  ParseParams,
  Reject,
  RequestContext,
  RestBindings,
  Send,
  SequenceHandler,
  StaticAssetsRoute,
} from '@loopback/rest';
import {AuthenticationBindings, AuthenticateFn} from '@loopback/authentication';

const SequenceActions = RestBindings.SequenceActions;

export class MySequence implements SequenceHandler {
  constructor(
    @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
    @inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
    @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
    @inject(SequenceActions.SEND) public send: Send,
    @inject(SequenceActions.REJECT) public reject: Reject,
    @inject(AuthenticationBindings.AUTH_ACTION)
    protected authenticateRequest: AuthenticateFn,
  ) {}

  async handle(context: RequestContext) {
    try {
      const {request, response} = context;
      const route = this.findRoute(request);

      // This is the important line added to the default sequence implementation
      if (!(route instanceof StaticAssetsRoute)) {
        await this.authenticateRequest(request);
      }

      // Authentication successful, proceed to invoke controller
      const args = await this.parseParams(request, route);
      const result = await this.invoke(route, args);
      this.send(response, result);
    } catch (err) {
      this.reject(context, err);
    }
  }
}

La sequence.ts mise à jour sera maintenant:

if (!(route instanceof StaticAssetsRoute)) {
  // do your login stuff here
}

p >


1 commentaires

StaticAssetsRoute a été supprimé, pouvez-vous mettre à jour votre réponse?



1
votes

J'utilise ce qui suit pour déterminer si l'itinéraire est statique.

private static isStaticRoute(route: ResolvedRoute): boolean {
  return route.path.search(/^\/explorer\/*/) === 0;
}


0 commentaires