skip to Main Content

I use Symfony 5 and React, with docker.

Both container are on different docker-compose but on the same newtork, so they can see and ping each other.

Now I want to POST something on one of my api route, here is my request:

const handleSubmit = async function (e) {
        setError(null)
        setLoading(true)
        e.preventDefault()
        const data = new FormData(e.target)
        console.warn(data)
        try {
            const response = await fetch('https://localhost:8443/authentication_token', {
                credentials: 'include',
                headers: {
                    Accept: 'application/json',
                },
                method: 'POST',
                body: data,
            })

            console.warn(response)
            const responseData = await response.json()
            console.warn(responseData)
            onConnect(responseData)
        } catch (e) {
            setError(e)
            setLoading(false)
        }
    }

Then I’m getting the following error:

Access to fetch at 'https://localhost:8443/authentication_token' from origin 'http://localhost:3001' has been blocked by CORS policy: 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.

So after some search I installed nelmio package to deal with cors, here is my nelmio_cors.yml file:

nelmio_cors:
    defaults:
        allow_credentials: true
        allow_origin: ['*']
        allow_methods: [ 'GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ]
        allow_headers: [ '*' ]
        expose_headers: [ 'Authorization']
        max_age: 0
        hosts: []
        origin_regex: true
        forced_allow_origin_value: ~
    paths:
        '^/':
            origin_regex: true
            allow_origin: ['*']
            allow_headers: [ '*' ]
            allow_methods: [ 'POST', 'PUT', 'PATCH', 'GET', 'DELETE' ]
            expose_headers: [ 'Link' ]
            max_age: 3600

And added the below line in my .env:

###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN=(.*)
###< nelmio/cors-bundle ###

And yet I get the same error and didn’t manage to find an answer online.

Does anyone see what I’ve done wrong?

UPDATE

I’ve changed my nelmio_cors.yml config to the one above

And still got issues with cors but a different error message now:

Response {type: "cors", url: "https://localhost:8443/authentication_token", redirected: false, status: 404, ok: false, …}

It seems react don’t manage to find the route. Any idea why ?

UPDATE 2

My nelmio_cors.yaml file now looks like that :

nelmio_cors:
    paths:
        '^/':
            origin_regex: true
            allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
            allow_headers: ['*']
            allow_methods: ['POST', 'PUT', 'PATCH', 'GET', 'DELETE']
            max_age: 3600

.env contains:

CORS_ALLOW_ORIGIN=(.*)

But on the route call I receive the following error :

Access to fetch at 'https://localhost:8443/authentication_token' from origin 'http://localhost:3001' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.

My response headers

access-control-allow-origin: http://localhost:3001
cache-control: no-cache, private
content-encoding: gzip
content-length: 451
content-type: application/json
date: Thu, 22 Oct 2020 08:12:11 GMT
server: openresty/1.17.8.2
status: 404
vary: Accept-Encoding
vary: Accept
x-debug-exception: Unable%20to%20find%20the%20controller%20for%20path%20%22%2Fauthentication_token%22.%20The%20route%20is%20wrongly%20configured.
x-debug-exception-file: %2Fsrv%2Fapi%2Fvendor%2Fsymfony%2Fhttp-kernel%2FHttpKernel.php:141
x-debug-token: 9b2891
x-debug-token-link: https://localhost:8443/_profiler/9b2891
x-powered-by: PHP/7.4.11
x-previous-debug-token: 486328
x-robots-tag: noindex

request header:

:authority: localhost:8443
:method: POST
:path: /authentication_token
:scheme: https
accept: application/json
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
content-length: 248
content-type: multipart/form-data; boundary=----WebKitFormBoundarywFASHmBarrNFyL7Y
cookie: pma_lang=fr; phpMyAdmin=a18f394d8e7daaefba20691da57c4b58; io=Jh7QElIlIXLDeAYaAAAA
origin: http://localhost:3001
referer: http://localhost:3001/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36

2

Answers


  1. Chosen as BEST ANSWER

    For those who have the same issue, the problem came from the frontend

    The data I recovered and place in body :

    
    const response = await fetch(
                    'https://localhost:8443/authentication_token', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',  
                    },
                    body: data
                })
    

    were not well formated, and for some reason the backend sent back weird errors.

    So I hardcoded them and this final result work :

    const data = "{"email":"[email protected]","password":"test"}";
                const response = await fetch(
                    'https://localhost:8443/authentication_token', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',  
                    },
                    body: data
                })
    

  2. I would suggest to have a different environmental variable value for local development and for your production or non-production environments.

    nelmio_cors:
        paths:
            '^/':
                origin_regex: true
                allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'PATCH', 'GET', 'DELETE']
                max_age: 3600
    

    For local development you may have the following env.

    CORS_ALLOW_ORIGIN=(.*)
    

    For prod/non-prod you may want to list your web applications domains explicitly in order to be on a safe side.

    CORS_ALLOW_ORIGIN=^https://(www.)?(site.domain.com|site2.domain.com)$
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search