Reputation: 4811
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)
})
}
Upvotes: 2
Views: 2804
Reputation: 76
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
Upvotes: 1
Reputation: 472
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') {}
Upvotes: 1