Cloudflare SSL: Express Not Working After SSL Appli - node.js

Please consider my circumstance:
I have created a backend API on port 8880 in Express.js in HTTP
I have created a frontend website in Next.js on port 80, also in HTTP.
I signup with cloudflare they manage my DNS, I get their SSL so my frontend HTTP site becomes HTTPS.
After successfully applying SSL to the frontend, the backend api stops receiving the POST request from login from the frontend.
As a result, I can no longer login to my site because every attempt fails when the POST request attempts to send the JSON payload of the login. How can I fix this SSL brokenness? This worked perfectly fine as HTTP to HTTP. But now, as HTTPS to HTTP, got failure.
Here is what I have tried to solve:
HTTPS to HTTPS - this failed. I tried changing the backend to HTTPS but used a self-signed certificate following this instruction.
My code in app.js (backend):
https.createServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
}, app)
.listen(port, function () {
console.log(`Connected on port ${port}`)
})
Set up my Cloudflare Page Rules - Apparently cloudflare has "Page Rules" settings for your domain so I set mine to domainname.com/api SSL: Flexible. Still failed. Testing in Postman showed I was successfully signing in with https://123.456.789.10:8880/api/signin but not with https://domainname.com/api. I enabled morgan on Express and saw no ping on the /api/signin endpoint.
Switching the backend from HTTPS to HTTP, leaving Page Rules on SSL Flexible - As per this answered question here, I was thinking this will surely work since Cloudflare says "The Flexible SSL option allows a secure HTTPS connection between your visitor and Cloudflare, but forces Cloudflare to connect to your origin web server over unencrypted HTTP. An SSL certificate is not required on your origin web server and your visitors will still see the site as being HTTPS enabled." Doing this also failed.
And so, I am still unable to reach /api/signin either on domainname.com/api/signin or https://123.456.789.10:8880/api/signin or http://123.456.789.10:8880/api/signin. Morgan shows nothing in the console when I attempt signin, whereas it did before.
SOMEBODY out there must have solved setting up a frontend and backend on one IP but two different ports and gotten it to work with cloudflare SSL before. Please help!

I was able to solve this by implementing NGINX and setting the config to take / and /api and make them route to the respective apps running their port numbers. Additionally, I had to set up cors in my Express backend and used dotenv to allow a .env file to persist the FRONTEND_APP environment variable containing the ip address of the frontend Next.js app.

Related

send requests from react app to express app (Get SSL)

I'm using React for the front end and express for the back end, I deployed my front end to cPanel and got SSL certificate.
but the express app runs on http://ip:port and not on a domain with https URL which means I cant send requests from the front end to non SSL IP's.
how I can get SSL certificate or secure the backend app? and also how i change the express app to https:// instead of http, with the https node module? or there is another, better way?
and how i can connect the ip to a domain name, like "api.mydomain.com" or even set it to run on "mydomain.com/api" (way better if possible)..
thanks!

After connecting SSL certificate to the frontend, requests are not sent to the backend

Everything worked fine. But after after adding the SSL certificate to the frontend, requests are not sent to the backend. Backend has SSL certificate as well. Any ideas how I can fix it? Also added a forced use https.
In browser console I get: xhr.js:177 POST 188.221.82.95:3001/submitVideo/storageSize net::ERR_CONNECTION_CLOSE

Send cookies from nodejs server on ReactJs application

How i red here, if i need to send cookie from nodejs to react application both app should be on the same port. Doing this on the server: res.cookie('token', token, { httpOnly: true }); i can send the cookies on front-end if i have the same ports, but here appear the issue if the both apps are on the same port, because if i access on front end for example http://localhost:4001/login and my server also is on http://localhost:4001, i can get the 404 error, because in this way i access the server route http://localhost:4001/login not front-end. Question: So How to solve this issue when the routes mess with each other and to be able to send the cookies?
One of the solutions is to use domains instead of ports.
For this purpose you can launch an edge web server locally (for instance Nginx or Apache) with port forwarding and set mapping from your domain to your localhost.
Also, you can use one of the plenty of services that can expose your local web servers to the Internet. Probably it could be the easiest one for you. Here is the sequence of actions then you can apply to resolve the issue:
Step 1
Run frontend and backend apps on two different ports, let's say 4001 for the backend app and 4002 for the frontend app. As a result of the step, you have to be sure that both apps are up and running and accessible via ports.
Step 2
Sign up and install https://ngrok.com/ or any other service which can expose your local app to the internet with a domain.
If you will choose ngrok, my suggestion is to write a configuration file and place it in the default location. (default location of config-file depends on your OS - here is the link to the documentation: https://ngrok.com/docs#config-default-location)
Here is the example of a config file:
authtoken: // place your ngrok access token here
region: eu
tunnels:
frontend_app:
proto: http
addr: 4002
backend_app:
proto: http
addr: 4001
Don't forget to place your authtoken, to get one you have to signup.
For more information about setup ngrok, please check the official documentation: https://ngrok.com/docs#getting-started-expose
https://ngrok.com/docs#tunnel-definitions
As a result after you launch ngrok you have to get the next output in the console:
Forwarding http://569de0ddbe4c.ngrok.io -> localhost:4002
Forwarding https://93b5cdf7c53f.ngrok.io -> localhost:4001
And be able to access your local apps via generated external addresses.
Step3
The last two things you have to do are:
Replace your API endpoint with an external URL (https://93b5cdf7c53f.ngrok.io in my example) in your frontend app.
Tweak res.cookie call in the backend app to make possible access cookies from both domains: res.cookie('token', token, { httpOnly: true , domain: 'ngrok.io' })
That's it. Now your apps are accessible from the Internet by different third-level domains with shared cookie between them.

node stripe deployment issue

I made a react add with node backend using the stripe express checkout form, and passing the source and other data to the backend to subscribe users, but on production it does not work.
I have it on an ubunutu vps, and the app is served with nginx as a reverse proxy of localhost. but it is not working, i also added ssl certificate to the domain but I am getting an error now that says:
Blocked loading mixed active content “http://localhost:8080/api”
on the server version in stripe test mode.
how can this be fixed?
In production it is required that you use SSL with Stripe. Your error is because you are trying to load or access http://localhost:8080/api from an originally https page. Stripe requires that all of your resources are loaded via https/SSL.
You also probably shouldn't be loading localhost in production. You should be using your actual hostname in production with https.
Let's say you load https://example.com/ in your browser. And you want to make a call to your backend server that is running on https://example.com/api. Instead of specifying localhost you can just change the URL to be /api and that will automatically append the domain name https://example.com to the request. This only works for the same domains. If it's separate domains you have to specify the domain name in your request.

Users behind corporate firwall can't access SSL site using HAProxy

I am totally stumped on this one. I recently installed SSL certificates on my site and SSL terminates at my load balancer, HAProxy. So far all of my regular users are able to use the secure connection except for those behind one major corporate network.
Those behind the network get this message in Chrome:
"This webpage is not available" "The
webpage at https://example.com/ might be temporarily down or it may
have moved permanently to a new web address."
Error Code: ERR_CONNECTION_CLOSED
They can access http://example.com site just fine (no SSL) if I enable it.
I was originally wondering if it was an issue with my ciphers, but these corporate users cannot access files on static server either (using AWS Cloudfront with SSL certificate).
I'm guessing the firm may have a blanket ban on SSL certificates unless there is a whitelist? They can access the ssl site of google (https://google.com). Is there something wrong with my certificate? Chrome has a green lock and says my site uses modern cryptography.
Anyway, is there anyway to determine if they can't access my site via SSL and then redirect them to use the nonsecure version? I tried looking through HAProxy docs but am missing something and at this point have tunnel vision.
Thanks to all. Here is my config file:
global
tune.ssl.default-dh-param 2048
ssl-default-bind-options no-sslv3
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
mode http
option forwardfor
option http-server-close
option http-pretend-keepalive
timeout client 120s
timeout connect 10s
timeout tunnel 120s
timeout client-fin 120s
timeout server 120s
frontend https-www
bind *:443 ssl crt /etc/ssl/example_com/example.com.pem
#using naked domain
redirect location https://example.com if { hdr_beg(host) -i www }
acl is_sockjs path_beg /sockjs
use_backend sockjs if is_sockjs
default_backend django
frontend all
bind *:80
#How do I detect that the ssl site failed for them?
redirect scheme https if !{ ssl_fc }
backend sockjs
reqadd X-Forwarded-Proto:\ http
balance leastconn
cookie SERV_ID prefix nocache
server srv_sockjs1 sockjsserver-ip check cookie s1
backend django
reqadd X-Forwarded-Proto:\ https
balance roundrobin
server srv_static django-server-ip
backend django-nonssl
reqadd X-Forwarded-Proto:\ http
balance roundrobin
server srv_static django-server-ip
OK figured it out
It was related to the naked domains. The server didn't like the fact that I redirected https://www.example.com to https://example.com. Upon further reading, I am going to now do the opposite, where I don't support naked domains and now redirect https://example.com to https://www.example.com
I had to do this on cloudfront too, where I now use www.subdomain.example.com instead of example.com

Resources