React Front-end connecting to Java Backend on Gitpod HTTPS - gitpod

I have a project which I have dockerised here: https://github.com/redis-projects/redis-movies/tree/gitpod
I am in the process of trying to get it to work correctly on GitPod, however I am having issues with the frontend react app hitting the backend java service. The react app is running in my local browser so I am confused by which network settings I should use and how to correctly configure.
The docker-compose file when used locally can simply use localhost:8080 to interact with the backend services, but GitPod generates a unique domain over HTTPS. Currently this causes the issues:
Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<URL>'. This request has been blocked; the content must be served over HTTPS.
This is self-explanatory, I cant make HTTP requests when the site is loaded via HTTPS. & even if I could, its pointing # localhost so the service wont resolve.
How can I setup my docker-compose + gitpod configuration to correctly configure the React URL
Currently use env vars:
REACT_APP_MOVIE_SERVICE_HOST=localhost
REACT_APP_MOVIE_SERVICE_PORT=8080
and this simply builds a url like so (apiConfig.js): http://${process.env.REACT_APP_MOVIE_SERVICE_HOST}:${process.env.REACT_APP_MOVIE_SERVICE_PORT}
Assuming that the backend services are exposed via a public endpoint, I will need to handle any CORs issues since these services are no longer 'local'?

Related

frontend cloud run app can not access my backend cloud run app due a MixedContent problem

I have two cloud services up and running.
frontend (URL: https://frontend-abc-ez.a.run.app/)
backend (URL: http://backend-abc-ez.a.run.app/)
Frontend is calling the backend through a nuxt.js server middleware proxy to dodge the CORS problematics.
The call is coming through - I can see that in the backend log files. However the response is not really coming back through because of CORS. I see this error in the console:
Mixed Content: The page at 'https://frontend-abc-ez.a.run.app/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://backend-abc-ez.a.run.app/login'. This request has been blocked; the content must be served over HTTPS.
What I find weird is that I configured the backend url with https but it is enforced as http - at least that is what the error is telling me. Also I see a /login path segment in the unsecure URL. Why is that? I never explicitly defined that endpoint. Is it the security layer proxy of the run service itself?
Anyway - I need to get through this properly and am having a hard time to understand the source of the problem.
For some reason as I rechecked the applications today in the morning everything went fine. I have really no idea why it is working now. I did not change a thing - I waited for the answers here before I'd continue.
Very weird. But the solution so far seems to be waiting. Maybe Cloud Run had some troubles.

Call APIs over Http from Webpage served over Https

We have a Java/Jetty server. The servlets on this server are called by some of our internal applications over http.
I have been asked to create a webapp /website which will use many of these servlets / api.
However this is an external customer facing website and needs to be served over https / ssl. The servelet urls look like
http://internalServer:9999?parameters.
Now my webapp is ready and has been deployed on Apache on Debian. Everything works fine but as soon as I enable
https/ssl the backend calls do not go through. On chrome I get "Mixed content. Page was loaded on https but is requestig resource over http...". On Safari I get -could not load resource due to access control checks.
I understand the reasons for these errors but I would like to know ways to solve this.
I have full control over apache server and website code.
I have very limited control over internal jetty server and no control over servelt code.(don't want to mess with existing apps).
Is there something I can do just with apache configuration? can I use it as a reverse proxy for the Jetty(http) server?
Thanks for your help.
"Mixed content. Page was loaded on https but is requestig resource over http..."
That error message means your HTML has resources that are being requested over http://... specifically.
You'll need to fix your HTML (and any references in javascript and css) that request resources (or references resources) to also use https://....
If you try to call an http service from an https site you will have Mixed content error.
You can avoid that error using apache2 proxy settings inside your example.org.conf
You can find it inside the folder /apache2/sites-enabled
Add some code:
<VirtualHost *:443>
...
ProxyPass /service1 http://internalServer:9999
ProxyPassReverse /service1 http://internalServer:9999
</VirtuaHost>
From your https site you have to fetch the url
https://example.org/service1`
to reach the service.
In that way you can call your services http from a https site.

Express Gateway: 'warn: unable to verify the first certificate' Express.js

I'm brand new to Express Gateway and I'm trying to set up a basic API Gateway to link up some micro services. When I try and proxy to a specific end point https://my-service.net/status (not the real URL), I get this error
[EG:policy] warn: unable to verify the first certificate
I can access the URL 'https://my-service.net/status' in the browser just fine.
When I switch out the serviceEndPoint URL it works fine (e.g. to https://httpbin.org), so it seems like there's something different with my URL in terms of the SSL/authentication config.
Any ideas? Many thanks.
My gateway.config.yml -->
So the SSL setup allows me to access the page from a browser (Chrome), but at the command line (e.g. through my Express Gateway which is served by NPM and running locally on port 8080) it fails.

Different ports for frontend and backend. How to make a request?

Using Angular-CLI as a frontend. 4200 port
Using Express as a backend. 8080 port
Directories look like:
Application
- backend
- ...Express architecture
- frontend
-...Angular2 architecture
So I'm running two projects, two commanders, one for frontent, second one for backend. node app.js for backend (8080), ng serve for frontent (4200).
Let's assume that I have a layer in backend which returns some string.
app.get('/hello', function(req, res) {
res.send("Hello!");
}
How can I make a request from frontend to backend and get that string? I don't want to know how exactly should I use Angular2 because that's not the point. I'm asking, what technology should I use to be able connect these two (frontent and backend) sides on different ports. If I just run them and make a request from frontend, I'll get an error because it can't find /hello url.
Your request to /hello means an absolute path inside the application running the angular application, so the request goes to http://localhost:4200/hello. Your angular application just doesn't know about the express application you want to target.
absolute urls
If you want to access the hello route on the other (express) application, you need to explicitly specify this by referencing http://localhost:8080/hello.
cors
Doing it this way, the correct application is targeted, but you will likely run into CORS issues, because the browser will prevent the javascript code obtained from localhost:4200 to access a server at localhost:8080. This is a security feature of your browser. So if you want to allow the code at 4200 to access the backend at 8080 your backend can whitelist this so called origin. For details see http://enable-cors.org/ and a corresponding express middleware you could use to support cors in your backend (https://www.npmjs.com/package/cors).
Using this approach has two downsides in my opinion. First, you need a way to tell your frontend under which absolute url it can reach the backend. This must be configurable because you need different urls for dev, staging and production. You then also need a way to manage all your whitelisted urls because the frontend in production will have a different url than when running the frontend in development. This can get pretty cumbersome to handle.
proxying your backend
A better approach in my opinion is to handle this in your infrastructure by proxying the backend in your frontend application. With proxying you basically tell your frontend server that all requests to some url should be passed through to another application. In your case this could probably mean, that for example you configure a proxy for the path /api/ to proxy the application on localhost:8080. The server then doesn't try to find a url like /api/hello on your frontend application but forwards your request to localhost:8080/hello. In your angular application you then don't need to care about the url of your backend and you can then always do a request to a url like /api/some-express-route.
For this to work you need to configure your angular dev server to proxy the requests. For details on how to do this, please see the docs at https://angular.io/guide/build#proxying-to-a-backend-server. When going to production, you can do this by configuring your web server, e.g. nginx to proxy the requests.

'XMLHttpRequest cannot load' Error on HTTP Requests from Dart client to local Dart docker server

I've lately been trying to build a Dart client that communicates with my Dart docker server. If I run this url (localhost:8080/id/6192449487634432) on any browser I get back a JSON that I've set up, however, if a use
HttpRequest
.getString ("http://localhost:8080/id/6192449487634432")
.then (print);
on the Dart client, I get this weird error
XMLHttpRequest cannot load http://localhost:8080/id/6192449487634432. No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access.
I've searched and some workarounds have been to build a PHP proxy (no thanks). I am new to web development in general and I definitely don't know what a proxy is or how to build one. Is there a clean solution I could use? I have a Redstone server and and AngularDart client.
This happens when your client app is served from a different server than your docker server. This is a browser issue, not specific to Dart. Luckily, the solution is easy.
Be sure to send CORS headers from your server, on every request. The easiest way to solve this is to add the following header:
Access-Control-Allow-Origin: *
I don't know the specifics of Redstone, but be sure to set the header key Access-Control-Allow-Origin and value * on GET, HEAD, and POST methods. Yes, you need to set this header on HEAD requests because sometimes the browser does a HEAD request to check if CORS is enabled.
Learn more about CORS at http://enable-cors.org/
As mentioned above setting the Access-Control-Allow-Origin header allows HTTP requests from the browser to go to other URLs than the origin the client was loaded from. Another option is to serve the Dart client from the same server as you are accessing.
Depending on your environment and whether you are using Dartium or a JavaScript browser
If you are using Dart on App Engine Managed VMs we have built-in support for this, so that requests for the client files are proxied to pub serve during development and served from the output from pub build when deployed. See A Client-Server Example.
If you are running a plain Dart server right now there is no canned solution for switching between pub serve and pub build. You can run pub build and serve the files out of the web/build directory.
We are working on making the solution provided for Dart on App Engine Managed VMs more generally available.
Particularly to redstone, you can solve the problem as follows. Add to your server-side code this snippet
// if not yet there
import 'package:redstone/server.dart' as app;
#app.Interceptor(r'/.*')
interceptor() {
app.chain.next(() {
app.response = app.response.change(headers: {
"Access-Control-Allow-Origin": "*"
});
});
}
you can read more on interceptors in the redstone wiki