No 'Access-Control-Allow-Origin' header is present on the requested resource with CORS module enabled - express

I am trying to get CORS working on my AWS Lambda server using Serverless. Right now I have two sub-domains (api.site.co and app.site.co).
In my app.js file on Express, I have installed CORS and enabled it like such:
app.use(
cors({
origin: 'https://app.site.co',
optionsSuccessStatus: 200,
}),
);
app.options('*', cors());
And then using the Axios module in React, I make this call:
axios
.post('/users/register', user)
.then(res => history.push('/login'))
.catch((err) => {
dispatch({
type: GET_ERRORS,
error: err.response.data,
});
});
Also, in my app.js file for the client app:
axios.defaults.baseURL = 'https://api.site.co';
When submitting any request, I receive this error:
Access to XMLHttpRequest at 'https://api.site.co/users/register' from origin 'https://app.site.co' 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.
So, far I have also tried changing my CORS configuration to:
app.use(cors());
app.options('*', cors());
But I am still getting the same error.
Any suggestions on how to address this?

Looks like there is a typo:
https://app.site.co/users/register => https://api.site.co/users/register
You're making a request to https://api.site.co but your configuration specifies https://app.site.co

This was a problem with the AWS Lambda Serverless setup. I needed to add
functions:
app:
handler: app.handler
events:
- http:
path: /
method: any
cors:
origin: 'https://app.site.co'
- http:
path: '{proxy+}'
method: any
cors:
origin: 'https://app.site.co'
So that it would allow CORS requests when proxying to the Express middleware.

Related

get CORS problem when ty to get a token in keycloak with vuejs and axios

I trying to access one keycloak with axios in my vuejs app, but I receive the cors error, can someone help me please? (If I make a post from POSTMAN to my keycloak works fine)
I using this code:
const params = new URLSearchParams();
params.append("grant_type", "password");
params.append("client_id", "notas-front");
params.append("username", usuario.value);
params.append("password", password.value);
console.log(params);
const config = {
// withCredentials: true,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
};
axios.defaults.headers.common["Access-Control-Allow-Origin"] =
"http://localhost:8080";
axios
.post(
"http://localhost:8082/auth/realms/lumera/protocol/openid-connect/token",
params,
config
)
.then((response) => {
console.log(response);
});
and get this error:
but when I look the request I can't find the error:
the OPTIONS returns 200
but the POST dont
Postman doesn't care about Same Origin Policy, browser do. That's why your request is working in Postman but not in the browser.
Access-Control-Allow-Origin is a response header, you can't set it on the client request. And as you can see from the OPTIONS response headers your server is returning: Access-Control-Allow-Origin: http://localhost:8080
In a development environment the best way to solve this is setting a proxy in your vue configuration. Otherwise you should configure the server to allow requests from localhost:8080
Configure Web Origins properly in the Keycloak notas-front client config.

APIGateway CORS enabled and Lambda proxy integration enabled but still running into CORS issues

I have the following CDK code for my API Gateway
this.restAPI = new RestApi(this, name, {
cloudWatchRole: true,
domainName: {
domainName: props.recordName,
certificate: props.cert,
endpointType: EndpointType.REGIONAL,
securityPolicy: SecurityPolicy.TLS_1_2
},
defaultCorsPreflightOptions: {
allowOrigins: Cors.ALL_ORIGINS,
allowMethods: ['OPTIONS', 'POST', 'GET', 'DELETE', 'PUT', 'PATCH'],
allowHeaders: Cors.DEFAULT_HEADERS,
maxAge: Duration.seconds(86400)
}
});
which results in this
But I'm still running into this error:
/#/actors:1 Access to fetch at 'https://web-api.alpha.myapp.com/api/v1/actors?page=1' from origin 'https://alpha.myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
But if you look at my Access-Control-Allow-Origin it's set to '*'. So I'm not sure what I'm missing.
And just to validate I do have Lambda Proxy integration turned on
Apparently my lambda that returns the GET content actually has to include the relevant CORS headers. It's not enough to just turn on CORS support on API Gateway.

ses.sendmail() gives CORS error. 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'..credentials mode is 'include'

I have been stuck on this for 4 days now. I really need some insights.
I have a serverless express app deployed on AWS. I am serving my frontend from S3 and backend from lambda. API gateway has proxy as shown in the serverless.yml below.
I have also used cloudfront to map my domain(https://my.domain.com.au) with the S3 bucket origin URL.
The normal GET POST PUT DELETE requests are working fine. But when I try to access any of the other AWS service from Lambda I get following CORS error.
Access to XMLHttpRequest at 'https://0cn0ej4t5w.execute-api.ap-southeast-2.amazonaws.com/prod/api/auth/reset-password' from origin 'https://my.domain.com.au' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
My use case is to send a mail from my app for which I tried using.
ses.sendEmail(params).promise();
This gave me the same error. So i tried invoking it through lambda, same error. Now i am trying to push mail contents to S3 and send mail from lambda using trigger but this gave me the same error.
The issue doesn't seem to be on the code as its working perfect from local environment. However, i don't want to leave any stones unturned.
Since, my lambda is in a VPC i have used internet gateway and tried setting up the private link as well.
Serverless.yml
service: my-api
# plugins
plugins:
- serverless-webpack
- serverless-offline
- serverless-dotenv-plugin
# custom for secret inclusions
custom:
stage: ${opt:stage, self:provider.stage}
serverless-offline:
httpPort: 5000
webpack:
webpackConfig: ./webpack.config.js
includeModules: # enable auto-packing of external modules
forceInclude:
- mysql
- mysql2
- passport-jwt
- jsonwebtoken
- moment
- moment-timezone
- lodash
# provider
provider:
name: aws
runtime: nodejs12.x
# you can overwrite defaults here
stage: prod
region: ${env:AWS_REGION_APP}
timeout: 10
iamManagedPolicies:
- 'arn:aws:iam::777777777777777:policy/LambdaSESAccessPolicy'
vpc:
securityGroupIds:
- ${env:AWS_SUBNET_GROUP_ID}
subnetIds:
- ${env:AWS_SUBNET_ID1}
- ${env:AWS_SUBNET_ID2}
- ${env:AWS_SUBNET_ID3}
environment:
/// env variables (hidden)
iamRoleStatements:
- Effect: "Allow"
Action:
- s3:*
- ses:*
- lambda:*
Resource: '*'
# functions
functions:
app:
handler: server.handler
events:
- http:
path: /
method: ANY
- http:
path: /{proxy+}
method: ANY
cors:
origin: ${env:CORS_ORIGIN_URL}
allowCredentials: true
headers: 'Access-Control-Allow-Origin, Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization'
method: ANY
# you can add CloudFormation resource templates here
resources:
# API Gateway Errors
- ${file(resources/api-gateway-errors.yml)}
# VPC Access for RDS
- ${file(resources/lambda-vpc-access.yml)}
I have configured response headers as well:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", process.env.CORS_ORIGIN_URL);
res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
next();
});
I actually have the same exact error as you but I've figured it out.
I'll just paste my code since you didn't show what your lambda function looks like.
I also know its been two weeks... so hopefully this helps someone in the future.
CORS errors are server side, and I'm sure you are aware. The problem with AWS SES is you have to handle the lambda correctly or it'll give you a cors error even though you have the right headers.
First things first... I don't think you have OPTIONS method in your api gateway...although I'm not sure if ANY can work as a replacement.
Second here is my code:
I check which http method I'm getting then I respond based on that. I am receiving a post event and some details come in the body. You might want to change the finally block to something else. The OPTIONS is important for the CORS, it lets the browser know that its okay to send the POST request (or at least that's how I see it)
var ses = new AWS.SES();
var RECEIVER = 'receiver#gmail.com';
var SENDER = 'sender#gmail.com';
exports.handler = async(event) => {
let body;
let statusCode = '200';
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,DELETE,POST,PATCH,OPTIONS',
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Headers': 'access-control-allow-credentials,access-control-allow-headers,access-control-allow-methods,Access-Control-Allow-Origin,authorization,content-type',
'Content-Type': 'application/json'
};
console.log(event);
try {
switch (event.httpMethod) {
case 'POST':
event = JSON.parse(event.body);
var params = {
Destination: {
ToAddresses: [
RECEIVER
]
},
Message: {
Body: {
Html: {
Data: html(event.name, event.phone, event.email, event.message), // 'Name: ' + event.name + '\nPhone: ' + event.phone + '\nEmail: ' + event.email + '\n\nMessage:\n' + event.message,
Charset: 'UTF-8'
}
},
Subject: {
Data: 'You Have a Message From ' + event.name,
Charset: 'UTF-8'
}
},
Source: SENDER
};
await ses.sendEmail(params).promise();
break;
case 'OPTIONS':
statusCode = '200';
body = "OK";
break;
default:
throw new Error(`Unsupported method "${event.httpMethod}"`);
}
}
catch (err) {
statusCode = '400';
body = err.message;
}
finally {
body = "{\"result\": \"Success\"}"
}
console.log({
statusCode,
body,
headers,
})
return {
statusCode,
body,
headers,
};
}

CORS not working on apollo-server-express

Package: apollo-server-express
Version: v2.6.0
Issue: CORS settings aren't taking effect.
Reported to Apollo?: Yes, Issue 3058
Description: From our react client, we started sending apollographql-client-name & apollographql-client-version headers for better client awareness in Apollo Engine.
Access to fetch at 'https://something.com/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field apollographql-client-name is not allowed by Access-Control-Allow-Headers in preflight response.
We receive above CORS error. We enabled cors on Apollo Server through express middleware by passing cors: true. For some reason, this changes are not making any difference. We continue to receive above error.
const server: ApolloServer = new ApolloServer({
...
...
});
const app: Application = express();
server.applyMiddleware({
app,
cors: true,
path: '/graphql',
});
We have nginx sitting in front and it does receive request and forwards to Apollo Server.
cors: true enables everything by default?
We tried being very specific but that didn't help either.
cors: {
origin: true,
allowedHeaders: ['Authorization', 'Content-Type', 'apollographql-client-name']
},
Any inputs and suggestions are welcome!
Issue is resolved.
We had kubernetes ingress layer on top of our Apollo Server and that's what was causing changes not to reflect. After we enabled cors on nginx ingress, we were able to make successful calls.

CORS issues after deploying Express.js API to Heroku

I've tried everything I could find on CORS issues, but I can't seem to solve it. I'm using a React.js app with Express.js API to handle the mailer function. When running it locally I did get CORS issues and solved it like this:
const cors = require('cors')
app
.use(cors())
.use(bodyParser.urlencoded({ extended: true }))
.use(bodyParser.json())
.use(mailer)
I deployed React app and Express API to Heroku, and suddenly started getting CORS errors again:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://...' is therefore not allowed access. The response had HTTP status code 503.
So I tried several different ways to make it work but none of it helps, some examples:
app
.use(bodyParser.urlencoded({ extended: true }))
.use(bodyParser.json())
.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'https://florismeininger.herokuapp.com');
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
.use(mailer)
app
.use(cors({origin: 'https://florismeininger.herokuapp.com'}))
.use(bodyParser.urlencoded({ extended: true }))
.use(bodyParser.json())
.use(mailer)
app
.use(cors({origin: '*'}))
.use(bodyParser.urlencoded({ extended: true }))
.use(bodyParser.json())
.use(mailer)
So it was a 503 error in response to a preflight OPTIONS request.
I worked around sending this request by using multipart/form-data and attaching the body:
var data = new FormData()
data.append('body',body)
api.post('/mailer', { attach: body })
Now I'm getting a new POST 503 error and also this error:
Failed to load https://florismeininger-mailer-api.herokuapp.com/mailer: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://florismeininger.herokuapp.com' is therefore not allowed access. The response had HTTP status code 503. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I tried using the 'no-cors' mode also but didn't work. Keep getting the No 'Access-Control-Allow-Origin' header is present error.
If you are getting the 503 in response to a CORS preflight OPTIONS request, then as #sideshowbarker comments, the problem is that the OPTIONS request method probably isn't allowed by your web server (Apache or whatever).