AWS-issued certificate failure - node.js

I have a certificate issued by AWS for my domain, and as informed I configured it on register.com. Problem is that when I open the site with www.example.com it appears as an invalid certificate, but when I open it directly with https://example.com it appears a valid certificate.
I am using NodeJS as a server, how do I redirect to always open the domain like https://example.com ?
Now is working like this:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Locale, X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, Content-Encoding');
res.setHeader('Access-Control-Expose-Headers', 'Locale');
if ((req.headers["x-forwarded-proto"] || "").endsWith("http")) {
res.redirect(`https://${req.headers.host}${req.url}`);
}
next();
});
My certificate

You have to register your SSL certificate for both www.example.com and example.com. Registering only one, will not work because www.example.com will be considered as different than example.com.

Related

CORS issue in API gateway lamba-proxy integration

I'm currently on a serverless application and my serverless.yml looks like
functions:
app:
handler: server.run
events:
- http:
path: /api/{any+}
method: ANY
- http:
path: /secure/api/{any+}
method: ANY
cors :
origins
- domain-url-1
- domain-url-2
As you can see above one is a secured route and that requires authorization whereas the non-secure route doesn't require any authorization headers to be passed. Since lambda-proxy doesn't take api gateway response I'm attaching the response headers on my app.js as below and for every route I'm sending the status and status codes separately in res objects.
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Request-Headers", "*");
// res.headersSent("Access-Control-Allow-Headers", "Content-Type");
res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept, Authorization, accesstoken");
res.header('Access-Control-Allow-Credentials', true);
next();
});
But my api gateway works fine for non-secure routes while for secure routes I'm getting a CORS issue with
** Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
polyfills.ff5fcb5319b1dc651f7b.js:1 GET https://8nv8r4ph65.execute-api.us-east-1.amazonaws.com/staging/secure/api/v1/legal/notification/list?rowsPerPage=15 net::ERR_FAILED **
I'm not sure where I'm going wrong.
Your origin header does not match specified domains in ApiGateway. For fast verification remove specified domains in serverless.
This is because your secured routes are using one of the methods to pass authentication status that the browser detects as being a request with credentials. Some of the ways a browser marks a request as credentialed is if the request sends back a cookie or if the request includes the Authorization header.
Credentialed requests have an additional rule regarding CORS. The origin * is illegal for credentialed requests. Browser manufacturers instead want server admin/backend developers to tell the browser exactly what domain name is valid for the CORS request.
In addition to the rule above, list of domain names are also illegal for credentialed requests. A request with credentials can only accept one domain for CORS.
You can of course hardcode the domain name of your frontend in your server code. But this gets annoying and is not flexible in case you need to serve multiple domains.
The correct working solution for this scenario (indeed, the way CORS was intended to be used) is to check the Origin header in the request.
The laziest way to make it work is to simply copy the Origin header to Access-Control-Allow-Origin:
res.header("Access-Control-Allow-Origin", req.get("Origin"));
This will allow anyone in the world from any website to access your data. This is perfectly fine if you are OK with this and only care about using authentication to protect your data instead of also using the CORS mechanism.
If you are using the cors middleware you it will do this for you if you pass true as origin:
app.use(cors({ origin: true }));
The way CORS is intended to be used is to check the Origin against a list of approved domains:
const approvedDomains = [
"https://www.google.com",
"https://my.application.com",
"http://my.application.com" // etc..
]
function checkDomains(origin) {
return approvedDomains.filter(domain => domain === origin)[0];
}
res.header("Access-Control-Allow-Origin", checkDomains(req.get("Origin")));
Again, the cors middleware makes this simple allowing you to pass an array of approved domain names and it will do the above logic for you:
app.use(cors({ origin: approvedDomains });

Azure Functions: sudden CORS issue (after hours of copacetic development)

Getting this error "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource ..."
But I had been developing from my localhost:* just hours before. I did nothing to the application settings or CORS settings. Now I have a wildcard and it still doesn't work (above error).
I checked out {app}.scm.azurewebsites.net/Env.cshtml and I see:
...
APPSETTING_WEBSITE_CORS_SUPPORT_CREDENTIALS = True
...
WEBSITE_CORS_SUPPORT_CREDENTIALS=False
...
I don't know if these environment variables are correct or if they changed since my functions were actually working.
While I've found a solution, it probably makes sense to address this problem anyhow.
const proxy = require('express-http-proxy');
const app = require('express')();
const subdomain = '';
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:1234');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use('/', proxy(`https://${subdomain}.azurewebsites.net`));
app.listen('9091', () => {
console.log('Proxy on http://localhost:9091')
})
Then just pass in proxyUrl as a parameter if you want to preconfigure HATEOAS links.
I think that Azure App Service CORS is taking precedence over your application CORS settings. Quoting from another reply "If you enable one origin domain in App Service, and enable all domains in your Web API code your Azure API app will only accept calls from the domain you specified in Azure".
Here is the link to the other thread: Enable Access-Control-Allow-Credentials header in Azure website (Azure App Services)
I hope that you find this answer helpful :)

How do I properly make api calls in deployment using create-react-app with an expressjs backend?

I am trying to deploy a react application to the server.
When my deployed app tries to make calls to an api on the same server it receives the following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3045/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘http://xxx.xxx.x.xx:5000’).
The package.json file has the proxy specified:
"proxy": "http://localhost:3045",
And here is my api call:
fetch('/login',
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
password
})
})).json()
What confused me further, when I had the site being served from the remote server, accessed it from my own local machine, and had the backend being served on my local machine, the site was making calls to my own local port(successfully, once I noticed what was going on and changed the cors config origin to the remote server's ip to test), and accessed the api being served from my local machine, instead of on it's (the remote deployment server's) own local port.
My cors config on the remote server api:
app.use(
cors({
origin: 'http://localhost:5000',
credentials: true,
}),
What changes do I need to make so that my site is making api calls to its own local ports, instead of the clients?
From memory (and running into a similar issue) proxying isn't mean to work when you deploy.
See Create-React-App Proxy in Production Build
Try setting it up without any special cors module:
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5000');//If it doesn't work, change it to "*"
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,token');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});

What does cors middleware do?

Was looking at some node js code which created some web API's
and came across this:
//CORS Middleware
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,
contentType,Content-Type, Accept, Authorization");
next();
});
Have looked around on the internet and can't seem to understand what it does?
Can someone please explain the purpose of cors middleware
This link may help.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
CORS allows you to configure the web API's security. It has to do with allowing other domains to make requests against your web API. For example, if you had your web API on one server and your web app on another you could configure CORS in your Web API to allow your web app to make calls to your web API.

Node.js CORS resulting in 403 Forbidden

Our website uses the HTML5 fetch API to make a call to our backend NodeJS service for certain actions. Our backend resides on a different domain to main website, so we have CORS enabled on the Node app. This works for 99% of our clients.
However, one client has been having issues. They are trying to access our website from their workplace (maybe their workplace network has higher security settings..?) and they're receiving the following error:
api.our-node-backend.com/blah Failed to load resource: the server
responded with a status of 403 (Forbidden) book:1 Fetch API cannot
load https://api.our-node-backend.com/blah. Response to preflight request
doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin
'https://www.our-frontend-website.com' is therefore not allowed
access. The response had HTTP status code 403. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.
Our Node app is currently configured as follows:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// respond to options pre-flight
app.options('*', function(req, res) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.status(200).send();
});
Is there something wrong with this configuration? Other examples on stack overflow have Access-Control-Allow-Headers set to "Origin, X-Requested-With, Content-Type, Accept" instead of just "Content-Type". What difference does that make?

Resources