sourcefuse / loopback4-starter

Loopback 4 starter application. Multi-tenant architecture supported. Authentication, Authorization, Soft deletes, environment vars, Audit logs, included.
MIT License
158 stars 59 forks source link

CORS not operational #77

Closed arnaud16571542 closed 3 years ago

arnaud16571542 commented 3 years ago

Describe the bug In my env developement, my front-end use localhost:3000, et my loopback backend use localhost:3001. Because front & end use different URL, the browser use CORS to check if the front is allow to request the backend. The browser send OPTIONS request, and get a reply "403 Forbidden".

My FrontEnd can't authentify to the backend (@post('/auth/login') because of this behaviour. I try to trace the request: i checked my login controller & sequence : but the request is blocked somewhere else.

To Reproduce

Expected behavior With a correct ApplicationConfig (see below), CORS should be authorized for all requests & origin.

Screenshots na

Additional context

My ApplicationConfig :
  const config: ApplicationConfig = {
    rest: {
      cors: {
        origin: '*',
        methods: 'OPTIONS, GET,HEAD,PUT,PATCH,POST,DELETE',
        preflightContinue: false,
        optionsSuccessStatus: 204,
        maxAge: 86400,
        credentials: true
      },
      port: +(process.env.PORT ?? 3001),
      host: process.env.HOST,
      gracePeriodForClose: 5000, // 5 seconds
      openApiSpec: {  setServersFromRequest: true   },
    },
  };

My login-controller:

@authenticateClient(STRATEGY.CLIENT_PASSWORD)
  @authenticate(STRATEGY.LOCAL)
  @authorize({ permissions: ['*'] })
  @post('/auth/login', {
    responses: {
      [STATUS_CODE.OK]: {
        description: 'Auth Code',
        content: {
          [CONTENT_TYPE.JSON]: Object,
        },
      },
    },
  })
  async login(
    @requestBody() req: LoginRequest,
  ): Promise<{ code: string; }> {
akshatdubeysf commented 3 years ago

Hi @arnaud16571542,

Looks like the Authorization component is the part that is giving the 403 response. Can you try using the invokeMiddleware sequence action in the sequence before all the authentication and authorization, as CORS is handled in one of these middlewares. Please refer this on how to invoke middlewares in an action based sequence.

Your sequence should look something like this -

...
      const { request, response } = context;
      const finished = await this.invokeMiddleware(context);
      if (finished) {
        // The response been produced by the middleware chain
        return;
      }
      const route = this.findRoute(request);
      const args = await this.parseParams(request, route);
...
arnaud16571542 commented 3 years ago

You are the big boss : it works ! Several hours to troubleshoot this problem and trying to avoid it solved in 10min... I'm still wondering why I didn't saw this solution.

By the way, maybe this should be included by default in loopback-starter as the default sequence (provided by the bare loopback package) offer this functionality.

That's great, I can now focus on migrate my JWT login interface to these new authentification providers. Thank you for your help !