[ERR] SSL_accept failed. Aborting handshake. CORS Problem
I´m trying to send a POST request from a vue web app to ESP32 https sever. If i use postman or curl it works fine, but i cant get it work from firefox vue app.
This is what I get in ESP32 log:
83981534 HTTPSServer->debug: [-->] New connection. Socket fid is: 0x3A 83982447 HTTPSServer->debug: [ERR] SSL_accept failed. Aborting handshake. 83982448 HTTPSServer->debug: [<--] Connection has been closed. fid = 0x3A 83982449 HTTPSServer->debug: [ ] Free headers
In firefox I get CORS error.
I´m managing CORS like in examples, with this node:
ResourceNode * corsNode = new ResourceNode("/*", "OPTIONS", &corsCallback);
secureServer->registerNode(corsNode);
void corsCallback(HTTPRequest * req, HTTPResponse * res) {
Serial.println(">> CORS here...");
res->setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Headers", "*");
}
CORS is enforced in the browser, not on the server side. As long as the server responds with the right headers for the OPTIONS request (you can check that with curl), the server lib most likely won't be the problem.
Note that the code will not match every OPTIONS request, as the pattern matching is quite limited up to now. Using the default handler or server->setDefaultHeader(...) might be a more general approach.
If you serve your vue app from file:// or http://localhost, be aware that browsers might have some peculiarities with XHttpRequests to external servers - Chrome does not allow it at all, Firefox might not be happy with the protocol switch etc... - The developer console should tell you what exactly is the problem in your case.
Thanks for the fast reply!
I´m running vue dev server locally in https:// ... I have just tried adding CORS headers with setDefaultHeader( ... ) and doesn´t work.
This is what I´m getting in firefox:
If I translated correctly, that should be this reason, so it doesn't even seem to be CORS-related.
Just to be sure it's not one of the usual suspects: Did you open a web page from the ESP32 directly in another tab, but within the same browser instance? You need to confirm the security exception for the self-signed certificate, but an XHttpRequest will not open a prompt, as it runs in the backend.
So did you open https://you-esp32-ip/ in another tab, confirm everything and then tried it again in the vue app?
Perfect! Thank you! It works!
How can i resolve this in a production environment? Only with a signed certificate? Can i use one certificate for a lot of devices? How can i use let´s encrypt?
Sorry for the late response.
How can i resolve this in a production environment? Only with a signed certificate?
You'll need a valid certificate. There are two scenarios:
a) You have control over the clients browser (e.g. within a company) – Then you can install your own CA in their trust stores and sign the ESP's certificate with that CA. You still need to have a matching domain name, but you can make something up if you also have control over DNS (would be something like xyz.intern.acme.org).
b) You don't have control. Then you need a valid domain name that you own and for that a public CA that is part of the default trust store of all browsers. That might not scale very well.
Can i use one certificate for a lot of devices?
You could do that, but one compromised device would mean that all devices are compromised. And they either need to share the same host name or all host names have to be listed as alternative host names. Scales even worse.
How can i use let´s encrypt?
That would be a good option, but I'm not aware if there's any implementation of the ACME protocol for the ESP32, but you would need that to refresh the certificate after three months.
So it really depends on what you're trying to achieve and in which environment that should work.