Search code examples
reactjscorsfetch

Failed to Fetch - Cors Error - When Fetching with Authorization Header - On Postman working OK


Hi everybody i'm trying to solve some issue.

I need to get some data, with my credentials.

If i do it on POSTMAN , with Auth Basic Authorization, i get the data, but when i try it on my code, which runs on the browser, i get on the console "TypeError: Failed to fetch" and on network i get this status "CORS error".

This is the code:

fetch(
      'https://content-us-8.content-cms.com/api/f8d92c5b-2ec6-46ee-8e22-cd2d9a556473/authoring/v1/content/views/by-type?id=5030aaad-9bf6-45db-9a3e-5cc7cd190103',
      {
        headers: {
          Authorization: 'Basic ' + base64.encode(userName + ':' + password)
        },
        withCredentials: true
      }
    )
      .then((el) => el.json())
      .then((el) => console.log(el))
      .catch((err) => console.log(err))
      .finally((el) => {
        console.log('FINALLY');
        console.log(el);
      });

If i do the call without headers i get this error:

{
    "requestId": "807bd27d2b28962b9d2834458e926499",
    "service": "prod-infra-api-dispatcher",
    "version": "0.0.1883",
    "description": "Acoustic Content, API Dispatcher Component",
    "errors": [
        {
            "name": "AccessControlError",
            "message": "The user 'undefined' tried to perform GET /content/views/by-type with tenant 'f8d92c5b-2ec6-46ee-8e22-cd2d9a556473'. Access to the service was denied because the user roles 'anonymous' do not match the accepted roles 'admin,manager,editor,viewer'. Verify that the user has the correct role assigned.",
            "locale": "en",
            "parameters": {
                "statusCode": 403,
                "method": "GET",
                "path": "/content/views/by-type",
                "roles": [
                    "anonymous"
                ],
                "requiredRoles": [
                    "admin",
                    "manager",
                    "editor",
                    "viewer"
                ],
                "timestamp": 1650811022658
            },
            "timestamp": "Sun, 24 Apr 2022 14:37:02 GMT"
        }
    ],
    "timestamp": "Sun, 24 Apr 2022 14:37:02 GMT",
    "message": "The user 'undefined' tried to perform GET /content/views/by-type with tenant 'f8d92c5b-2ec6-46ee-8e22-cd2d9a556473'. Access to the service was denied because the user roles 'anonymous' do not match the accepted roles 'admin,manager,editor,viewer'. Verify that the user has the correct role assigned."
}

I understand this error occurs because i'm not setting credentials... but i've tried multiple ways to achieve this without success.


Solution

  • The browser makes a cross-origin GET request with Authorization header only if the preceding preflight request succeeds. But as you can try out with curl:

    >curl -I -X OPTIONS -H "Access-Control-Request-Headers:Authorization"
     -H "Origin:http://localhost"
     https://content-us-8.content-cms.com/api/...
    
    HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: http://localhost
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Methods: GET,OPTIONS
    Access-Control-Allow-Headers: accept,accept-language,content-language,pragma,cache-control,x-xsrf-token,x-acoustic-region,x-acoustic-auth-source,x-ibm-dx-tenant-id,x-cms-user-auth,x-ibm-dx-user-auth
    Access-Control-Expose-Headers: cache-control,content-language,content-type,expires,last-modified,pragma,x-ibm-dx-request-id,x-response-time
    

    the Authorization header is not in the list of allowed headers. In other words: The service does not allow basic authentication in cross-origin requests.

    If you cannot influence the backend on content-cms.com so that Authorization becomes an allowed header, the only option is to tunnel the request through your own backend server. Or are you programming "server-less"?