Strongloop/loopback 4: how to disable authentication for Explorer component over REST?












1















I have followed and set up via @loopback/authentication
But the authentication is added to sequence.ts for all calls.
I am unable to skip authentication for Explorer component



My open source repo: opencommerce/questionnaire-server



Details:





  • application.ts has





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,
},
};
}
}





  • sequence.ts has





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);
}
}
}



Error while accessing / .



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)









share|improve this question




















  • 1





    Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

    – angelwally
    Jan 2 at 14:17











  • Sure I'll add the whole code today.

    – Milind Singh
    Jan 2 at 15:36











  • @angelwally I have added my github repo. Its the project in generated with lb4.

    – Milind Singh
    Jan 2 at 17:39











  • I don't see any controller with the path /. Do you have one?

    – angelwally
    Jan 2 at 17:46











  • github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

    – Milind Singh
    Jan 2 at 18:47
















1















I have followed and set up via @loopback/authentication
But the authentication is added to sequence.ts for all calls.
I am unable to skip authentication for Explorer component



My open source repo: opencommerce/questionnaire-server



Details:





  • application.ts has





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,
},
};
}
}





  • sequence.ts has





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);
}
}
}



Error while accessing / .



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)









share|improve this question




















  • 1





    Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

    – angelwally
    Jan 2 at 14:17











  • Sure I'll add the whole code today.

    – Milind Singh
    Jan 2 at 15:36











  • @angelwally I have added my github repo. Its the project in generated with lb4.

    – Milind Singh
    Jan 2 at 17:39











  • I don't see any controller with the path /. Do you have one?

    – angelwally
    Jan 2 at 17:46











  • github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

    – Milind Singh
    Jan 2 at 18:47














1












1








1








I have followed and set up via @loopback/authentication
But the authentication is added to sequence.ts for all calls.
I am unable to skip authentication for Explorer component



My open source repo: opencommerce/questionnaire-server



Details:





  • application.ts has





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,
},
};
}
}





  • sequence.ts has





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);
}
}
}



Error while accessing / .



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)









share|improve this question
















I have followed and set up via @loopback/authentication
But the authentication is added to sequence.ts for all calls.
I am unable to skip authentication for Explorer component



My open source repo: opencommerce/questionnaire-server



Details:





  • application.ts has





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,
},
};
}
}





  • sequence.ts has





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);
}
}
}



Error while accessing / .



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)






node.js loopbackjs v4l2loopback






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 6:59







Milind Singh

















asked Jan 1 at 16:58









Milind SinghMilind Singh

117114




117114








  • 1





    Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

    – angelwally
    Jan 2 at 14:17











  • Sure I'll add the whole code today.

    – Milind Singh
    Jan 2 at 15:36











  • @angelwally I have added my github repo. Its the project in generated with lb4.

    – Milind Singh
    Jan 2 at 17:39











  • I don't see any controller with the path /. Do you have one?

    – angelwally
    Jan 2 at 17:46











  • github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

    – Milind Singh
    Jan 2 at 18:47














  • 1





    Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

    – angelwally
    Jan 2 at 14:17











  • Sure I'll add the whole code today.

    – Milind Singh
    Jan 2 at 15:36











  • @angelwally I have added my github repo. Its the project in generated with lb4.

    – Milind Singh
    Jan 2 at 17:39











  • I don't see any controller with the path /. Do you have one?

    – angelwally
    Jan 2 at 17:46











  • github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

    – Milind Singh
    Jan 2 at 18:47








1




1





Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

– angelwally
Jan 2 at 14:17





Normally, you shouldn't have issues if you don't put the decorator Strategy on your endpoint. Could you post the code of your controller?

– angelwally
Jan 2 at 14:17













Sure I'll add the whole code today.

– Milind Singh
Jan 2 at 15:36





Sure I'll add the whole code today.

– Milind Singh
Jan 2 at 15:36













@angelwally I have added my github repo. Its the project in generated with lb4.

– Milind Singh
Jan 2 at 17:39





@angelwally I have added my github repo. Its the project in generated with lb4.

– Milind Singh
Jan 2 at 17:39













I don't see any controller with the path /. Do you have one?

– angelwally
Jan 2 at 17:46





I don't see any controller with the path /. Do you have one?

– angelwally
Jan 2 at 17:46













github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

– Milind Singh
Jan 2 at 18:47





github.com/opencommerce/questionnaire-server/blob/master/src/… this.component(RestExplorerComponent); It handles the / path and renders a swagger ui for the API. But when I add the authentication as in github.com/opencommerce/questionnaire-server/blob/master/src/… await this.authenticateRequest(request);results in exception as above.

– Milind Singh
Jan 2 at 18:47












2 Answers
2






active

oldest

votes


















1





+50









Your custom sequence does not skip the authentication for static route /.
It can be skipped auth as below:



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


Now the updated sequence.ts will be:



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);
}
}
}





share|improve this answer































    1














    One possible issue you can have is that you bind the values after setting your sequence. Then the bindings does not exist when Loopback tries to resolve them. You should put something more like this:



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

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

    this.sequence(MySequence);





    share|improve this answer
























    • Thanks but it didnt work. Anything else I need can try?

      – Milind Singh
      Jan 4 at 17:25






    • 1





      I tried your code, but there is no route for /. The one you're talking about is /explorer.

      – angelwally
      Jan 4 at 21:26











    • Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

      – Milind Singh
      Jan 5 at 8:03











    • Can you try above?

      – Milind Singh
      Jan 5 at 11:58











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997294%2fstrongloop-loopback-4-how-to-disable-authentication-for-explorer-component-over%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1





    +50









    Your custom sequence does not skip the authentication for static route /.
    It can be skipped auth as below:



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


    Now the updated sequence.ts will be:



    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);
    }
    }
    }





    share|improve this answer




























      1





      +50









      Your custom sequence does not skip the authentication for static route /.
      It can be skipped auth as below:



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


      Now the updated sequence.ts will be:



      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);
      }
      }
      }





      share|improve this answer


























        1





        +50







        1





        +50



        1




        +50





        Your custom sequence does not skip the authentication for static route /.
        It can be skipped auth as below:



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


        Now the updated sequence.ts will be:



        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);
        }
        }
        }





        share|improve this answer













        Your custom sequence does not skip the authentication for static route /.
        It can be skipped auth as below:



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


        Now the updated sequence.ts will be:



        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);
        }
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 8 at 12:55









        Risha TiwariRisha Tiwari

        813




        813

























            1














            One possible issue you can have is that you bind the values after setting your sequence. Then the bindings does not exist when Loopback tries to resolve them. You should put something more like this:



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

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

            this.sequence(MySequence);





            share|improve this answer
























            • Thanks but it didnt work. Anything else I need can try?

              – Milind Singh
              Jan 4 at 17:25






            • 1





              I tried your code, but there is no route for /. The one you're talking about is /explorer.

              – angelwally
              Jan 4 at 21:26











            • Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

              – Milind Singh
              Jan 5 at 8:03











            • Can you try above?

              – Milind Singh
              Jan 5 at 11:58
















            1














            One possible issue you can have is that you bind the values after setting your sequence. Then the bindings does not exist when Loopback tries to resolve them. You should put something more like this:



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

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

            this.sequence(MySequence);





            share|improve this answer
























            • Thanks but it didnt work. Anything else I need can try?

              – Milind Singh
              Jan 4 at 17:25






            • 1





              I tried your code, but there is no route for /. The one you're talking about is /explorer.

              – angelwally
              Jan 4 at 21:26











            • Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

              – Milind Singh
              Jan 5 at 8:03











            • Can you try above?

              – Milind Singh
              Jan 5 at 11:58














            1












            1








            1







            One possible issue you can have is that you bind the values after setting your sequence. Then the bindings does not exist when Loopback tries to resolve them. You should put something more like this:



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

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

            this.sequence(MySequence);





            share|improve this answer













            One possible issue you can have is that you bind the values after setting your sequence. Then the bindings does not exist when Loopback tries to resolve them. You should put something more like this:



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

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

            this.sequence(MySequence);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 4 at 11:24









            angelwallyangelwally

            887822




            887822













            • Thanks but it didnt work. Anything else I need can try?

              – Milind Singh
              Jan 4 at 17:25






            • 1





              I tried your code, but there is no route for /. The one you're talking about is /explorer.

              – angelwally
              Jan 4 at 21:26











            • Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

              – Milind Singh
              Jan 5 at 8:03











            • Can you try above?

              – Milind Singh
              Jan 5 at 11:58



















            • Thanks but it didnt work. Anything else I need can try?

              – Milind Singh
              Jan 4 at 17:25






            • 1





              I tried your code, but there is no route for /. The one you're talking about is /explorer.

              – angelwally
              Jan 4 at 21:26











            • Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

              – Milind Singh
              Jan 5 at 8:03











            • Can you try above?

              – Milind Singh
              Jan 5 at 11:58

















            Thanks but it didnt work. Anything else I need can try?

            – Milind Singh
            Jan 4 at 17:25





            Thanks but it didnt work. Anything else I need can try?

            – Milind Singh
            Jan 4 at 17:25




            1




            1





            I tried your code, but there is no route for /. The one you're talking about is /explorer.

            – angelwally
            Jan 4 at 21:26





            I tried your code, but there is no route for /. The one you're talking about is /explorer.

            – angelwally
            Jan 4 at 21:26













            Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

            – Milind Singh
            Jan 5 at 8:03





            Thanks for efforts. Just comment out the line await this.authenticateRequest(request); from sequence.ts and you'll see that / route is rendering a default html page i.e this.static('/', path.join(__dirname, '../../public')); in application.ts .

            – Milind Singh
            Jan 5 at 8:03













            Can you try above?

            – Milind Singh
            Jan 5 at 11:58





            Can you try above?

            – Milind Singh
            Jan 5 at 11:58


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997294%2fstrongloop-loopback-4-how-to-disable-authentication-for-explorer-component-over%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

            Npm cannot find a required file even through it is in the searched directory