CORS issues when running a dockerised FastAPI application - https

I have a fastapi application running and working just fine. I want to use my fastapi application to serve as backend for my react frontend deployed on firebase hosting (https). Running locally (http fastpi and react) I got it working by enabling CORS in FastAPI
from starlette.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
But when I deployed I realized that I couldn't serve fastapi as HTTP since my frontend is on HTTPS. I went ahead and created a kubernetes cluster in Google Cloud and ingressed my dockerised fastapi application (exposed as HTTPS). That works when I curl to my HTTPS fastapi endpoint but I'm getting CORS issues again in my react app and this time I don't know how to solve it. How come the above doesn't apply any longer?
The CORS error is
Access to fetch at 'https://my-api-domain' from origin 'https://my-frontend-domain' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
EDIT
I just did some further investigation and I can conclude that if I run my container locally with docker run then access-control-allow-origin is properly returned in the header. But when deployed on GKE then there are no access-control-allow-origin.
UPDATE
I've tried installing nginx ingress instead of GKE ingress but that complicates things regardin global static IP and google managed certificate. I need a solution that gives me
Global static IP (ok with GKE ingress)
Google Managed Certificate (ok with GKE ingress)
CORS enabled (ok with nginx ingress)
So I'm stuck atm!
LATEST UPDATE
I'm using Nginx Ingress Controller with cert-manager and it works like a charm. Bonus info: running everything with skaffold and kustomize as well - so many great tools

Adding the middleware after the default endpoint solved the issue for me.
app = FastAPI()
#app.get("/")
def home():
return {"message":"Health Check Passed!"}
app.add_middleware(CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],)

Posting this Community Wiki for better visibility as solution was mention in comment section.
If you would like to use CORS on Google Cloud Platform, you have to use Nginx Ingress and specific GCP annotation. More details about this you can find in this SO thread
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/enable-cors: "true"
Solution
Solution for this issue was to use Nginx Ingress Controller and Cert-Manager with proper annotations.
Also OP confirmed it's working.
I'm using Nginx Ingress Controller with cert-manager and it works like a charm. Bonus info: running everything with skaffold and kustomize as well - so many great tools

Related

Kubernetes service on HTTPS

Requirement: To set up a Kubernetes service that is publicly accessible on browser on HTTPS
I browsed through the internet and everywhere I saw nginx-ingress which can give https url.
I have ingress setup and its working as expected
But my doubt is, this ingress will only run on my local, as I make the changes in /etc/hosts file of local? How can I make https url publicly accessible? I want my load balancer service to be accessed publicly with HTTPS. I have my application running on GKE Cluster. Please guide

Spring App on GCP - Cloud Run - HTTPS only - This combination of host and port requires TLS

My Spring app uses lets encrypt and is https only. I did not include http to https thing, as it worked for me in postman with https:// format
When I deployed to Cloud Run, and mentioned the custom port (the port specified in spring)
and tested using URL from dashboard
https://..blah..run.app
I am getting error/message
Bad Request
This combination of host and port requires TLS.
What configuration is required on Cloud Run to resolve this?
The url as I see on service details page has htpps://...
EDIT:
If Cloudrun does not need me to take case of SSL, I can remove the application properties entries
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:key/keystore.p12
server.ssl.key-store-password=${lets.secret}
server.ssl.key-alias=someCertAlias
server.ssl.enabled=true
So Can I get an answer on whether to remove SSL from spring?
If cloudrun always uses http, all my calls use redirectConnector, which seems pointless
The Cloud Run Service listens on HTTP and HTTPS. Your application running in the container must listen on a port configured with HTTP only.
FYI: For a public facing web server, you should almost always enable HTTP. Otherwise, when a user enters www.example.com in the browser, the user will receive a connect error. This not always the case, for example .dev gTLDs, but is good practice. When a user connects to Cloud Run with the HTTP protocol, Cloud Run will redirect the user to HTTPS and connect to your application using the HTTP protocol.

aws elastic beanstalk / S3 The page was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint

I have a Spring boot application deployed using AWS Elastic Beanstalk, im using S3 bucket for my angular app.
I have generated certifacate using aws certifacate manager and created CloudFront Distribution so my angular app is loaded on https.
The problem is I am calling a rest API from Https deployed Application to Http Rest API.
I keep getting this error:
Mixed Content: The page at "https://mywebsite.com" was loaded over HTTPS, but requested an insecure XMLHttpRequest 'http://myendpoint'. This request has been blocked; the content must be served over HTTPS.
I tried generating my own certificate in my spring boot application it worked locally but once deployed on elastic beanstalk web services doesnt respond.
any tip on how use https / beanstalk ?
The error message sums the problem clearly. It would be a huge security issue to allow unencrypted data transfer, for seemingly securely encrypted web page.
Moreover, you don't really want to do SSL termination on your instances, for performance reasons, you don't want to manually manage keys an so forth.
In your situation, I would advise setting up a CloudFront distribution in front of your ALB (which I assume you have). That will solve your problems immediately, as CloudFront will automatically setup a domain for you and will expose your endpoints via HTTPS. Afterwards if you decide, you can easily setup a custom domain and certificates.
Finally, I recommend reading this article to make sure you avoid common pitfalls when configuring ALB and CloudFront.
Best, Stefan

How to add url prefix for server api with traefik?

I'm using traefik v2 as gateway. I have a frontend container running with host https://some.site.com which powered by traefik.
Now I have a micro-service server with multi services and all of them are listening on 80 port. I want to serve the backend server on path https://some.site.com/api/service1, https://some.site.com/api/service2 ...
I have tried traefik.http.routers.service1.rule=(Host(some.site.com) && PathPrefix(/api/service1)) but not worked and traefik.http.middlewares.add-api.addprefix.prefix=/api/service1 not worked too;
How can I implement this?
Can you post your services' docker-compose configuration?
If you use middlewares, you may need to specify the service. Like
traefik.http.routers.service1.middlewares=add-api
traefik.http.middlewares.add-api.addprefix.prefix=/api/service1

How can I proxy HTTPS requests using react-native

I have an HTTPS endpoint I want to access using a proxy. I tried several modules such as axios, requests and others. But it seems the proxy configs I put in aren't being used.
How can I access an endpoints through a proxy using react-native?
Thanks

Resources