Azure Serverless Function-Enabling CORS in response headers - javascript

I've got a serverless function on Azure, written in Javascript, returning some HTML and front end JS. The JS is supposed to access a blob file hosted remotely. Right now, it's throwing me CORS errors. Even though I've added Access-Control-Allow-Origin to the headers:
headers: {
'Content-Type': 'text/html',
'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Origin': 'https://tif.azurewebsites.net',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE',
'Access-Control-Allow-Credentials':'true',
'Access-Control-Allow-Headers': 'X-Requested-With,content-type',
'Access-Control-Allow-Headers' : 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'
}
The Content-Type header works perfectly.
What am I doing wrong here?

As discussed in the comments, since your JS code is accessing the Blob Storage you would need to configure CORS settings for Blob Storage. When configuring CORS settings, please make sure that all settings are correct. A slight mismatch in the settings would result in 403 error returned from Storage Service.
Based on your environment, here's what I would recommend:
Allowed Origins: https://tif.azurewebsites.net
Allowed Methods: Select all of the methods.
Allowed Headers: *
Exposed Headers: *

Related

CORS error if PUT has credentials 'include' and Content-Type at the same time

I am using JavaScript fetch() with following options:
window.fetch(path, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
mode: 'cors',
credentials: 'include',
redirect: 'follow',
referrerPolicy: 'no-referrer',
cache: 'no-cache',
body: JSON.stringify(data)
})
but I get error:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
and my Access-Control-Allow-Headers has wildcard *.
It works without Credentials
It works fine if I don't add credentials: include and turn OFF auth on API server.
It works without Content-Type
It works fine if I don't add headers: {'Content-Type': 'application/json'}, and keep auth ON on API server. It means it is sent with text/plain;UTF-8 but content is still JSON.
Headers
Headers from my API server:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: *
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: *
http://localhost:3000 is where is my front-end app running on.
Hints
If i get this error, devTools in Chrome are not able to show me response headers (Access-Control-Allow-Headers etc.) and request headers shows Provisional headers are shown with only content-type: application/json in it and in General there is not method: PUT (there is not method at all). So it looks like Chrome stopped it before firing.
Server is on different domain (intern web) and is running on http with SameSite: None without Secure but I have disabled security Cookies without SameSite must be secure in Chrome to walkaround it in development mode.
Is there any relationship between credentials, content-type and PUT? Is it possible to send PUT with credentials and application/json? If it is not possible - how should I send data with PUT method? FormData which are allowed content-type for cors are not supported by PUT.
See the MDN documentation for Access-Control-Allow-Headers:
The value * only counts as a special wildcard value for requests without credentials (requests without HTTP cookies or HTTP authentication information). In requests with credentials, it is treated as the literal header name * without special semantics. Note that the Authorization header can't be wildcarded and always needs to be listed explicitly.
You need to specify the headers you want to allow explicitly.
Changing Access-Control-Allow-Headers from wildcard * to explicit Content-Type did the trick for me.

ReactJS: has been blocked by CORS policy: Response to preflight request doesn't pass access control check

i get this fail on chrome:
Access to fetch at 'http://******/places?holiday_type=resort&currency=EUR&checkin=2019-11-01&checkout=2019-11-10&groups[]=1'
from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.
My Code is:
getPlaces = async () => {
try {
let response = await fetch(`${BASE_URL}/places?holiday_type=resort&currency=EUR&checkin=2019-11-01&checkout=2019-11-10&groups[]=1`,
{
method: 'GET',
headers: new Headers({
'Accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
'Access-Control-Request-Method': 'GET, POST, DELETE, PUT, OPTIONS',
'Authorization': 'Basic ' + Base64.encode(apiuser + ':' + apipassword) ,
}),
})
console.log(response)
} catch (error) {
console.log(error)
}
}
External APIs often block requests like this. I would guess that you are using something like an API-Key for your request which includes payment based on your calls. The problem is that every user can read your key when you call the API in your frontend. Thats why the server is block these.
You need to make a server on your own (e.g. with node.js), call your backend API and then "forward" your request the public API with your secret API key.
Server-to-Server requests won't be blocked and your users can't exploit your API key.
You should also make sure to that your backend server doesn't accepts request which is not your frontend if you want to make it public.
CORS works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. This must be configured in the server to allow cross-domain.
You can temporarily solve this issue by a chrome plugin called CORS.
copied from: How to allow CORS in react.js?
Reference: How to overcome the CORS issue in ReactJS?

Ionic service worker send OPTIONS for GET

I'm currently working with Ionic to get data from an API. Although it's been working for the last days, I don't know how it stopped working.
I am using #angular/http to make my requests. When not using any headers, my request goes to GET Method, and doesn't work because I need an Authorization token.
But, if I had Headers via:
let headers = new Headers();
headers.append('Authorization', this.bearerToken);
let options = new RequestOptions({ headers: headers });
It doesn't work either. The request goes to OPTIONS Method, and is returning:
Unauthorized header authorization
Is there anything I can do on Ionic to fix this, or should I warn the API developers in order to make them do some changes?
Edit: The API developers are using Symfony and Nelmio CORS Bundle to handle these settings
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
paths:
'^/': ~
As #Moshe mentionned, their configuration should contain some Access-Control-Allow-Headers, and they do apparently..
When it comes to HTTP Headers (such as Authorization) the client sends an OPTIONS request in order to check if the headers are accepted by server first. I've had a similar issue with my client-server relationship. You must enable authorization in Access-Control-Allow-Headers in your server.
Example:
header('Access-Control-Allow-Headers: Content-Type, Authorization');

How to enable CORS in OrientDb server-config.xml

Am using OrientDb database, I have setup Orientdb server in my system, OrientDb has exposed Http Api's. So am trying to call API http://localhost:2480/query/test2/sql/select * from OUser , From javascript using AJAX call, I have set headers
Accept : "application/json;charset=utf-8",
"Access-Control-Allow-Origin":"*",
'Access-Control-Allow-Methods': 'POST, GET, DELETE, HEAD, OPTION',
'Access-Control-Allow-Headers': 'Origin, x-requested-with, content-type, accept',
'Access-Control-Allow-Credentials': true
And also I enabled CROS in orientdb-server-config.xml
parameter name="network.http.additionalResponseHeaders" value="Access-Control-Allow-Origin:*;Access-Control-Allow-Credentials: true;Access-Control-Allow-Headers: Origin, x-requested-with, content-type, accept;Access-Control-Allow-Methods: POST, GET, DELETE, HEAD, OPTION"
parameter value="utf-8" name="network.http.charset"
Still am getting
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
How to enable CORS in OrientDb server?
Access-Control-Allow-* are response headers, not request headers. They are used so the server can give your JS permission to read its data (not so that your JS can give itself permission to read the server's data).
You are setting them as custom request headers (in your JavaScript).
The CORS spec requires that you have explicit permission to set custom request headers, and you don't have permission from the server to set those (and why would you? They are nonsense.).
Don't set them in the JS.

Setting authorization in native browser fetch

I'm coming across an issue where I can't seem to set the headers for a fetch request and I think I'm missing something
var init = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer myKey'
}
};
return fetch(url, init).then(function(response){...
When the request is inspected in the network tab, I'm not seeing the headers get set and instead see
Access-Control-Request-Headers:accept, authorization, content-type
when I would expect to see
Authorization: Bearer myKey
Content-Type: application/json
Accept: application/json
I've also tried using the native Headers() with zero difference.
Am I missing something here?
I was having the same issue and took a bit of investigating this evening. The problem is cross-origin resource sharing / CORS. With Fetch it is the default and it makes things considerably more complex.
Unless Both the origin and destination are the same it is a cross-domain request, and these are only supported if the request is to a destination that supports CORS ( Cross-Origin Resource Sharing ). If it does not then it will not go through. You'll usually see an error like No 'Access-Control-Allow-Origin' header is present on the requested resource
This is why you can not do Authorization headers on non-CORS sites; see #5 and basic headers
https://fetch.spec.whatwg.org/#concept-headers-guard
https://fetch.spec.whatwg.org/#simple-header
FORBIDDEN HEADER NAMES:
https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
https://fetch.spec.whatwg.org/#forbidden-header-name
And unfortunately, before you try the XMLHttpRequest route, the same applies:
This is the same with XMLHttpRequest:
https://www.w3.org/TR/XMLHttpRequest/#the-open()-method
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
http://arunranga.com/examples/access-control/credentialedRequest.html
Finally, your choices to move forward are:
1. JSONP
2. Write a proxy that is not in the browser
3. Put CORS on the destination server
This article sums it up nicely

Categories