Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React w/ Kubernetes deployed API giving cors error

This is different from other cors related questions

I am running my node backend-api on microservices on kubernetes deployed on Digitalocean. I have literally read all the blogs/forums related to this issue and haven't found any solution (specifically the ones related to Digitalocean).

I am unable to connect to the cluster via React application running on 'localhost:3000' or anywhere outside the kubernetes cluster.

It is giving me below error:

Access to XMLHttpRequest at 'http://cultor.dev/api/users/signin' 
from origin 'http://localhost:3000' has been blocked by 
CORS policy: Response to preflight request doesn't pass access 
control check: Redirect is not allowed for a preflight request.

The kubernetes cluster's loadbalancer is listening on "cultor.dev" which is set as a local domain in /etc/hosts. I am able to make it work using Postman!

NOTE: I have tried using cors package as well, it won't help. Also, it works fine if I run this react app inside of the kubernetes cluster which I do not want.

Ingress nginx config (tried using annotations mentioned on the official website):

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
    name: ingress-service 
    ## this tells ingress to pick up the routing rules mentioned in this config
    annotations: 
        nginx.ingress.kubernetes.io/default-backend: ingress-nginx-controller
        kubernetes.io/ingress.class: nginx 
        ## tells ingress to check for regex in the config file
        nginx.ingress.kubernetes.io/use-regex: 'true'
        # nginx.ingress.kubernetes.io/enable-cors: 'true'
        # nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
        # nginx.ingress.kubernetes.io/cors-allow-origin: "*"
        # nginx.ingress.kubernetes.io/cors-max-age: 600
        # certmanager.k8s.io/cluster-issuer: letsencrypt
        # kubernetes.io/ingress.class: nginx
        # service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"

One of the microservices config (tried cors package as well):

// APP SETTINGS
app.set('trust proxy', true);
app.use(json());
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', '*');
  res.header('Access-Control-Request-Headers', '*');
  if (req.method === "OPTIONS") {
    res.header('Access-Control-Allow-Methods', '*');
    return res.status(200).json({});
  }
  next();
});
like image 709
Karan Kumar Avatar asked Sep 17 '20 19:09

Karan Kumar


2 Answers

Okay, after alot of research and with the help of the other answers I did the following:

  1. I changed the request to the backend (from the client side) to https instead of http. This fixed the error Redirect is not allowed for a preflight request
  2. I changed the config ingress nginx config to get rid of the error multiple values in Access-Control-Allow-Origin :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    nginx.ingress.kubernetes.io/default-backend: ingress-nginx-controller
    kubernetes.io/ingress.class: nginx
    ## tells ingress to check for regex in the config file
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
      add_header Access-Control-Allow-Credentials true;
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"

I hope it helps others as well.

like image 193
Karan Kumar Avatar answered Oct 26 '22 18:10

Karan Kumar


Why are the cors settings commented?

nginx.ingress.kubernetes.io/configuration-snippet: |
  add_header Access-Control-Allow-Origin $http_origin;
  add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
  add_header Access-Control-Allow-Credentials true;

Same issue on GitHub

like image 31
Someone Special Avatar answered Oct 26 '22 17:10

Someone Special