skip to main content

CORS and file access

When accessing a file, the CORS system performs a preflight request before the two actual requests of access control and obtaining the file

The following example delves into the GraphQL Working-with-files use case, showing how the CORS system intervenes in the request phase for a file, once it has obtained the URL to access via REST.

After a brief detail on the flow that allows access to a file with CORS enabled, a typical success scenario will be shown, and information will be provided to resolve any errors.

Workflow #

When a client makes a REST request to retrieve a file from the Cloudlet, after obtaining its URL via a previous GraphQL query, the following steps are performed:

  • initially, an authenticated request of type GET is sent, which verifies that the user described by the included token authentication has the permissions (grant) to access the desired file. If the verification is positive, a unique access key is generated for the file;

  • subsequently, a second authenticated GET request is sent actually to obtain the file. This request is generated by redirect from the previous one and includes in the query string a series of parameters related to the access key to the file;

  • at the end, the access key is invalidated.

If the Cloudlet has CORS enabled (ENABLE_CORS property of the @sys@properties table set to true), the two authenticated requests are each preceded by a preflight request, whereby the client obtains a set of headers from the server that determines whether or not the server is authorized to access its resources.

Successful scenario #

Suppose we have a Cloudlet with CORS enabled, to which we have previously submitted a GraphQL query to request an image and have obtained the following URL:

https://<CloudletURL>/auth/file/image/7001/attribute1

At the moment we make the call via REST, we can see the flow of all the calls made to the server with their responses by opening the Developer Tools of our browser (for Google Chrome and Mozilla Firefox users, you can do it quickly by pressing the F12 key) and accessing the Network (for Chrome) or Network (for Firefox) tab. We’ll notice a first request with HTTP method OPTIONS: it’s the preflight for checking permissions:

Preflight for checking permissions

If our client is authorized, it starts the first request for the grant verification, which has HTTP method GET:

Get for permission check

At this point, the user’s permissions are checked, and if yes, the second preflight request (method OPTIONS) starts:

Preflight for file access

If again the client is authorized, we will have the last request actually to access the file (method GET):

Get for file access

Possible problems and solutions #

Enabling CORS can cause unexpected errors, especially if the client makes use of custom headers to include in requests. The two most common errors are as follows:

  • the header in question is not present in the list of accepted ones;
  • the preflight request is malformed.

Header not specified as accepted #

If the custom header is not included in the accepted list, represented by the contents of the Access-Control-Allow-Headers header in one of the preflight responses, the actual request may raise a CORS Request Blocked (CORB) error. In this case, ensure that the desired header is present in the Access-Control-Allow-Headers field of the configuration JSON included in the CORS_HEADERS property of @sys@properties (for more information, see the Configure CORS section).

Malformed preflight request #

In other cases, even though the custom header has been included within the accepted list, a CORS Request Blocked (CORB) error may still occur. A likely cause may be a malformation of the preflight request, which does not have the Access-Control-Request-Headers header. According to CORS behavior, the server responds to this request without sending a corresponding Access-Control-Allow-Headers with the list of covered headers, and this triggers a default behavior where a subset of headers considered standard by the HTTP protocol is accepted (for more information see the external references in this section). In this case, it will be necessary, if possible, to review the requests sent by the client, making sure that they include the Access-Control-Request-Headers header.