motiv-labs / janus

An API Gateway written in Go
https://hellofresh.gitbooks.io/janus
MIT License
2.79k stars 317 forks source link

CORS plugin doesn't return access control headers on OPTIONS method #321

Closed KenoKokoro closed 6 years ago

KenoKokoro commented 6 years ago

I am not sure if I have bad configuration or it is actually something wrong here, but I don't receive the CORS headers on the OPTIONSmethod. Since my client is web client, when I request POST method on the login route with application/json content type I can't actually hit the POST method, since the OPTIONS preflight request doesn't contains the required headers to continue with the request and I get Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. in console.

Reproduction Steps:

  1. I set up the janus proxy for the oauth service, this is my response from localhost:8081/apis/auth.json:
    {
    "name": "app-auth-server",
    "active": true,
    "proxy": {
        "preserve_host": false,
        "listen_path": "/oauth/*",
        "upstreams": {
            "balancing": "roundrobin",
            "targets": [
                {
                    "target": "http://auth.app.local/api/v1",
                    "weight": 0
                }
            ]
        },
        "insecure_skip_verify": false,
        "strip_path": true,
        "append_path": false,
        "enable_load_balancing": false,
        "methods": [
            "POST",
            "OPTIONS"
        ],
        "hosts": []
    },
    "plugins": [
        {
            "name": "cors",
            "enabled": true,
            "config": {
                "domains": [
                    "http://dashboard.local"
                ],
                "exposed_headers": [],
                "methods": [
                    "POST",
                    "GET",
                    "PUT",
                    "DELETE"
                ],
                "request_headers": []
            }
        },
        {
            "name": "rate_limit",
            "enabled": true,
            "config": {
                "limit": "150-M"
            }
        }
    ],
    "health_check": {
        "url": "",
        "timeout": 0
    }
    }
  2. When I hit the localhost:8080/oauth/auth/login route from postman with POST request I get the response expected from the auth service with the expected CORS headers (since I changed the origin in the request headers)
    Access-Control-Allow-Credentials →true
    Access-Control-Allow-Origin →http://dashboard.local
    Cache-Control →no-cache, private
    Content-Length →143
    Content-Type →application/json
    Date →Fri, 11 May 2018 06:44:35 GMT
    Server →nginx
    Vary →Origin
    X-Powered-By →PHP/7.2.3
    X-Ratelimit-Limit →60
    X-Ratelimit-Remaining →59
    X-Request-Id →9b4a530d-835d-4874-9cbc-e66a6d8647ca
  3. But whenever I hit the same route with OPTIONS method ( just like from browser ), those headers aren't present and also I noticed it proxies the request to the application, which I don't really need it, my CORS headers will be set on the gateway. And if I remove the OPTIONS from the proxy.methods i get 405 Method not allowed response. This are the headers from the OPTIONS request to localhost:8080/oauth/auth/login:
    Allow →POST
    Cache-Control →no-cache, private
    Content-Length →0
    Content-Type →text/html; charset=UTF-8
    Date →Fri, 11 May 2018 06:57:42 GMT
    Server →nginx
    X-Powered-By →PHP/7.2.3
    X-Request-Id →11b1b1e5-64bf-4123-b996-4112aa909132

    What I first tried was to setup a oauth server for janus, but I also got the same response there, and that's why I tested it like a regular proxy endpoint, not as a oauth server.

Shouldn't it hit the OPTIONS method and return the CORS response from the gateway? Have I done something wrong with the configuration?

Janus version: I don't know exactly I am using the docker image using docker-compose:

version: '3.3'
services:

  janus:
    image: quay.io/hellofresh/janus
    ports:
      - "8080:8080"
      - "8081:8081"
    volumes:
      - ./janus.toml:/etc/janus/janus.toml
      - ./apis:/etc/janus/apis

OS and version:

DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=18.3
DISTRIB_CODENAME=sylvia
DISTRIB_DESCRIPTION="Linux Mint 18.3 Sylvia"
vgarvardt commented 6 years ago

Hello @KenoKokoro. Can you please provide curl (Postman can provide it) for your OPTIONS request, if the issue is still valid.

KenoKokoro commented 6 years ago

Hello @vgarvardt

curl -X OPTIONS \
  http://gate.local/catalog/stores \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hdXRoLmpvY2FsaW8ubG9jYWxcL2FwaVwvdjFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNTMzNTY0OTk1LCJleHAiOjE1MzM3ODA5OTUsIm5iZiI6MTUzMzU2NDk5NSwianRpIjoiYjVIVXZLNnI3STlrczVjZyIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.yWZldR8D2zWaOvWKmByNvowEikgHbKHvpMmbneAfrM0' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://dashboard.local' \
  -H 'Postman-Token: ddf18513-4549-4f66-8e99-3096b82a13b4' \
  -d '{
    "difficulty": ""
}'

I still have the issue, if the method is GET, I can see the cors response headers, but not for OPTIONS method.

Thanks

locker1776 commented 6 years ago

@KenoKokoro I have been working on this issue non-stop for a week now. I seem to have figured out many of the problems. Do you want to work together and try to troubleshoot what is happening?

KenoKokoro commented 6 years ago

@locker1776 I would gladly help, but I have 0 knowledge of Go Lang, I am not sure if I am qualified enough to help you or provide a PR.

vgarvardt commented 6 years ago

@KenoKokoro you're missing CORS-required Access-Control-Request-Method header in your request: -H 'Access-Control-Request-Method: POST' for POST method in curl.

KenoKokoro commented 6 years ago

@vgarvardt Yes. All good now. Thanks a lot!