2

The documentation advises that CORS is enabled by default. But with the default CORS configuration, I am still getting CORS issues. Checking the response headers, no CORS headers are attached.

Access to XMLHttpRequest at 'http://localhost:8081/sessions' from origin 'http://local.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

// src/index.ts

if (require.main === module) {
  // Run the application
  const config: ApplicationConfig = {
    rest: {
      port: +(process.env.PORT ?? 8081),
      host: process.env.HOST,
      // The `gracePeriodForClose` provides a graceful close for http/https
      // servers with keep-alive clients. The default value is `Infinity`
      // (don't force-close). If you want to immediately destroy all sockets
      // upon stop, set its value to `0`.
      // See https://www.npmjs.com/package/stoppable
      gracePeriodForClose: 5000, // 5 seconds
      openApiSpec: {
        // useful when used with OpenAPI-to-GraphQL to locate your application
        setServersFromRequest: true,
      },
      cors: {
        origin: '*',
        methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
        preflightContinue: false,
        optionsSuccessStatus: 204,
        credentials: true,
      },
    },
  }
  main(config).catch((err) => {
    console.error('Cannot start the application.', err)
    process.exit(1)
  })
}
Serg
  • 2,248
  • 3
  • 27
  • 37
Clement
  • 3,051
  • 2
  • 22
  • 49

2 Answers2

1

I'm guessing this is a problem coming with newer versions of LB4. Here is a workaround you can put in MySequence (make sure you add the sequence in application.ts):

    async handle(context: RequestContext) {
        try {
            const { request, response } = context;
            // add this
            await this.invokeMiddleware(context, this.options);
            response.header('Access-Control-Allow-Origin', '*');
            response.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
            if (request.method == 'OPTIONS') {
                response.status(200)
                this.send(response, 'ok');
            } else {
                // end add this
                const route = this.findRoute(request);
                await this.authenticateRequest(request);
                const args = await this.parseParams(request, route);
                const result = await this.invoke(route, args);
                this.send(response, result);
            }
        } catch (err) {
            if (
                err.code === AUTHENTICATION_STRATEGY_NOT_FOUND ||
                err.code === USER_PROFILE_NOT_FOUND
            ) {
                Object.assign(err, { statusCode: 401 /* Unauthorized */ });
            }
            this.reject(context, err);
        }

Please don't mind all the other stuff such as auth/middleware, it's all about that if (request.method == 'OPTIONS') {}

0

I had the same issue, using MiddlewareSequence instead of DefaultSequence made the CORS errors disappear.

Just change the sequence.ts file to this:

import {MiddlewareSequence} from '@loopback/rest';

export class MySequence extends MiddlewareSequence {}

Check the docs for more detalis: https://loopback.io/doc/en/lb4/REST-middleware-sequence.html#use-the-sequence-for-your-rest-application