Cross-Origin Resource Sharing (CORS) is a mechanism for servers to indicate from where it may be accessed and allows browsers to block requests that are not permitted. For security reasons, browsers limits requests initiated from JavaScript to only those for the same site. To allow requests from other sites the server needs to send the right CORS headers with the response. Read more about CORS at MDN
Details
CORS is opt-in. The security measure is already in place in browsers to limit cross-origin requests, and CORS is a way to break out of this in a controlled manner where you can indicate exactly who can make a request and what requests can be made. In general it works like this:
A request is being initiated from a website, either through JavaScript or another venue, to a site different than the one it originates from.
The browser identifies that the request is cross-origin and sends an
OPTIONSrequest to the server with information about the request it intends to send (this is called a pre-flight request).The server responds with a 204 response giving the allowed types of requests that can be made for the resource.
If the original request conforms to the response the browser will then send the actual request.
The server responds to the actual request.
The client gets the response, but the browser will limit what information in the response it can access based on the information provided by the server in the pre-flight response.
As can be seen, a CORS request is slightly more complex than the standard request-response you normally think about. However, the pre-flight request can be cached by the browser and so, will not happen every time a ressource is accessed. While a site may employ a CORS policy the same way across all its endpoints it does not need to. It is fine to only turn on CORS for a subset of paths. In general it is a good rule of thumb to set up resource isolation for the paths that do not have CORS enabled.
Initialization
A new 'CORS'-object is initialized using the new() method on the
generator and pass in any settings deviating from the defaults
Usage
cors <- CORS$new(...) |
Fiery plugin
A CORS object is a fiery plugin and can be used by passing it
to the attach() method of the fiery server object. Once attached all
requests will be passed through the plugin and the policy applied to it
Methods
Method new()
Initialize a CORS object
Arguments
pathThe path that the policy should apply to. routr path syntax applies, meaning that wilcards and path parameters are allowed.
originThe origin allowed for the path. Can be one of:
A boolean. If
TRUEthen all origins are permitted and the preflight response will have theAccess-Control-Allow-Originheader reflect the origin of the request. IfFALSEthen all origins are deniedThe string
"*"which will allow all origins and setAccess-Control-Allow-Originto*. This is different than setting it toTRUEbecause*instructs browsers that any origin is allowed and it may use this information when searching the cacheA character vector giving allowed origins. If the request origin matches any of these then the
Access-Control-Allow-Originheader in the response will reflect the origin of the requestA function taking the request and returning
TRUEif the origin is permitted andFALSEif it is not. If permitted theAccess-Control-Allow-Originheader will reflect the request origin
methodsThe HTTP methods allowed for the
pathallowed_headersA character vector of request headers allowed when making the request. If the request contains headers not permitted, then the response will be blocked by the browser.
NULLwill allow any header by reflecting theAccess-Control-Request-Headersheader value from the request into theAccess-Control-Allow-Headersheader in the response.exposed_headersA character vector of response headers that should be made available to the client upon a succesful request
allow_credentialsA boolean indicating whether credentials are allowed in the request. Credentials are cookies or HTTP authentication headers, which are normally stripped from
fetch()requests by the browser. If this isTRUEthenorigincannot be*according to the specmax_ageThe duration browsers are allowed to keep the preflight response in the cache
Method add_path()
Add CORS settings to a path
Usage
CORS$add_path(
path = "/*",
origin = "*",
methods = c("get", "head", "put", "patch", "post", "delete"),
allowed_headers = NULL,
exposed_headers = NULL,
allow_credentials = FALSE,
max_age = NULL
)Arguments
pathThe path that the policy should apply to. routr path syntax applies, meaning that wilcards and path parameters are allowed.
originThe origin allowed for the path. Can be one of:
A boolean. If
TRUEthen all origins are permitted and the preflight response will have theAccess-Control-Allow-Originheader reflect the origin of the request. IfFALSEthen all origins are deniedThe string
"*"which will allow all origins and setAccess-Control-Allow-Originto*. This is different than setting it toTRUEbecause*instructs browsers that any origin is allowed and it may use this information when searching the cacheA character vector giving allowed origins. If the request origin matches any of these then the
Access-Control-Allow-Originheader in the response will reflect the origin of the requestA function taking the request and returning
TRUEif the origin is permitted andFALSEif it is not. If permitted theAccess-Control-Allow-Originheader will reflect the request origin
methodsThe HTTP methods allowed for the
pathallowed_headersA character vector of request headers allowed when making the request. If the request contains headers not permitted, then the response will be blocked by the browser.
NULLwill allow any header by reflecting theAccess-Control-Request-Headersheader value from the request into theAccess-Control-Allow-Headersheader in the response.exposed_headersA character vector of response headers that should be made available to the client upon a succesful request
allow_credentialsA boolean indicating whether credentials are allowed in the request. Credentials are cookies or HTTP authentication headers, which are normally stripped from
fetch()requests by the browser. If this isTRUEthenorigincannot be*according to the specmax_ageThe duration browsers are allowed to keep the preflight response in the cache
Method on_attach()
Method for use by fiery when attached as a plugin. Should
not be called directly.
Examples
# Setup CORS for a sub path allowing access from www.trustworthy.com
# Tell the browser to cache the preflight for a day
cors <- CORS$new(
path = "/shared_assets/*",
origin = "https://www.trustworthy.com",
methods = c("get", "head", "post"),
max_age = 86400
)
# Use it in a fiery server
app <- fiery::Fire$new()
app$attach(cors)