Add common CORS headers in Mountebank responses - javascript

React app that is using mounteback as mock server, I am getting this error
Access to fetch at 'http://localhost:8080/xxx/api/secured/policies' from origin 'http://localhost:3000' 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.
I managed to find this with regards to OPTIONS pre-flight
https://groups.google.com/g/mountebank-discuss/c/G7TRM87Pocs
But even this is not enough, I had to had:
{
"is": {
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*"
}
}, ...truncated...,
}
For all the response stubs (I tried one and works, so means I need to do it for all).
Is there any way I can add this headers in one central location so that I don't need to add this to all stubs (its an existing project with half-baked mocks, that are not working, had to use CORS-unblock plugin without this change)?

I found the solution which is using the defaultResponse field which will return the CORS setting whenever no stub match is found.
Additionally if a stub match exists, it merges the stub response with defaultResponse hence all stubs will have this CORS settings in a central location as per my requirement.
According to docs:
"The default response to send if no predicate matches. Also represents
the default values that get merged into a response that doesn't
specify every field"
http://www.mbtest.org/docs/protocols/http
This is the solution that I have landed and works for me (no need to add CORS to each individual stub):
{
"imposters": [
{
"port": 8080,
"protocol": "http",
"defaultResponse": {
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*"
}
},
"stubs": [
<% include policy/sample1.json %> <%# truncated the list of json files which was about 20+ %>
]
}
]
}

Related

Cross-Origin Read Blocking (CORB) problem with KrakenD - "application/json" response from POST rejected by Chrome

auth.js:84 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://myserver/auth with MIME type application/json.
This doesn't work with Firefox either, although the Firefox error message is more generic. Oddly enough, Firefox's Network panel shows that the response I wanted actually gets delivered, the browser just doesn't accept the response to pass it on to my JavaScript code.
This is the CORS setup from my krakend.json file:
"github_com/devopsfaith/krakend-cors": {
"allow_origins": ["http://localhost:61552"],
"allow_headers": ["Origin", "Authorization", "Content-Type", "Accept", "X-Auth-Token", "Referer", "User-Agent"],
"expose_headers": ["Content-Type", "Content-Length"],
"allow_credentials": true,
"allow_methods": ["GET", "HEAD", "POST", "OPTIONS"]
}
And this is the particular endpoint being called:
"endpoints": [{
"endpoint": "/auth",
"method": "POST",
"output_encoding": "no-op",
"extra_config": {
"github.com/devopsfaith/krakend-ratelimit/juju/router": {
"maxRate": 20,
"clientMaxRate": 8,
"strategy": "ip"
}
},
"backend": [{
"url_pattern": "/connect/token",
"encoding": "no-op",
"sd": "dns",
"host": ["identity-server.service.consul"],
"disable_host_sanitize": true
}]
},
My JavaScript request looks like this:
xhr.open('POST', url);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.withCredentials = true;
xhr.onreadystatechange = function () {
...
}
xhr.send(...
I thought of trying to change the content type of the response to text/plain in case that would help, but I don't currently have access to the code that generates that response, and I don't know if that would help anyway.
When I make this same request from either a node.js server or an app like Postman, everything comes back correctly, and the headers I'd want to see that I think should be enough to make CORS happy are present (access-control-allow-credentials: true, access-control-allow-origin: *)
I finally found any answer for this.
The first problem was that, when using xhr.withCredentials = true, it isn't good enough to get a response header of access-control-allow-origin: *. The response header must contain the original origin of the request itself, such as access-control-allow-origin: https://example.com.
The second problem was the way the CORS module used by kraken deals with wildcard domains. If you use "allow_origins": [] or "allow_origins": ["*"], the server responds with access-control-allow-origin: * no matter what.
I didn't want to have to whitelist every host that might want to use this server, however.
Fortunately, someone was able to point me at the source code used by kraken to handle CORS (at https://github.com/rs/cors), and it turns out that if you use any other kind of wildcard expression other than "*" for everything, like "http*", then the server echoes back the original host, and all is well! My config is now:
"allow_origins": ["http*"]
NOTE: Doing this could be dangerous! If you're putting sensitive data into cookies, that same data can become available to any other websites this way.

Access-Control-Allow-Origin issue in ktor cors header

I am building a simple REST API using ktor and used cors but when i send a simple get request with no headers data the server works fine but if i want the client to have say key:1 the server doesn`t respond me correctly, it says the problem is
Failed to load http://127.0.0.1:8080/test: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
so here is my ktor code
install(ContentNegotiation) {
gson {
}
}
install(ForwardedHeaderSupport)
install(DefaultHeaders)
install(CORS)
{
method(HttpMethod.Options)
method(HttpMethod.Get)
method(HttpMethod.Post)
method(HttpMethod.Put)
method(HttpMethod.Delete)
method(HttpMethod.Patch)
header(HttpHeaders.AccessControlAllowHeaders)
header(HttpHeaders.ContentType)
header(HttpHeaders.AccessControlAllowOrigin)
allowCredentials = true
anyHost()
maxAge = Duration.ofDays(1)
}
...
get("test"){
val a = call.request.headers["key"]
println(a)
call.respond(Product(name = a))
}
and my javascript code looks like this....
fetch('http://shop-ix.uz:8080/test', {
headers: {
"key": "1"
})
.then(response => response.json())
.then(json => {
console.log(json);
})
please help me
You need to whitelist your headers like this:
install(CORS) {
header("key")
}
This needs to be done with every custom HTTP header you intend to use.
Make sure all the headers and required methods should be allowed during Ktor CORS installation. I was facing the same issue, then I realized that I didn't add allowHeader(HttpHeaders.AccessControlAllowOrigin)
Although in the request header it was present. Because of that I am getting forbidden error (403)!
My Request Header!
Axios({
method: 'GET',
url: 'http://127.0.0.1:8080/connect',
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
params: {
...
}
})
Allowing CORS
install(CORS) {
allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Post)
allowMethod(HttpMethod.Get)
allowHeader(HttpHeaders.AccessControlAllowOrigin)
allowHeader(HttpHeaders.ContentType)
anyHost()
}
Check that what your request header wants is allowed on the server during CORS.
install(CORS) {
exposeHeader("key")
}
difference between header and exposeHeader - first allow to make call with this header, but second allow to use it on client side

Getting the HTML source of a page in NodeJS

I'm currently struggling to get the HTML source of a webpage in NodeJS due to cors restrictions. Using JQuery I'm making a GET request to a page expecting an HTML response. This however throws the error XMLHttpRequest cannot load https://www.reddit.com/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. Is there a way to bypass CORS using NodeJS? (like via proxy)
$.ajax({
url: 'https://www.reddit.com/',
headers: {
'Content-Type': 'text/html',
"Access-Control-Allow-Origin": '*'
},
type: "GET",
data: {
},
success: function (result) {
console.log(result);
},
error: function () {
console.log("error");
}
});
I'm also using webpack dev server with the following headers
headers: {
"Access-Control-Allow-Origin": '*',
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS"
}
Do not use jquery in nodejs, you can use this libs to archieve what you need:
isomorphic-fetch
request
Hope it helps

Angular 4 - No 'Access-Control-Allow-Origin' header is present on the requested resource

I'm trying to get some data with Spotify / Musixmatch API in my Angular 4 app but it is not working. I keep getting this error:
XMLHttpRequest cannot load
http://api.musixmatch.com/ws/1.1/album.get?album_id=14250417&apikey=xyz010xyz.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access.
JS
let headers = new Headers();
headers.append('Content-Type','application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Headers', "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding");
let options = new RequestOptions({ headers: headers });
console.log(options)
return this.http.get(this.url + 'album.get?album_id=' + album_id + '&apikey=' + this.apikey, options)
.map(res => res.json())
}
This is the problem with browser, typically its a security concern not to allow other requests which may lead to XSS attack easily.
If only for development I suggest you to install a plugin which will disable in your browser
plugin
If for production, then you need to configure your API.
First, you have to create a file called proxy.conf.json, then put the following code
{
     "/ restapiserver / *": {
         "target": "http: // localhost: 8075",
         "secure": false,
         "changeOrigin": true
     }
}
In the service file, in the url of the rest service, delete the domain and leave the root of the service
private url: string = '/ restapiserver /';
PS: In AngularJS 4
Try this if not yet problem solved by setting header in js.
Add "no access control allow origin" plugin/add-on in chrome.
Yo can find here:NoAccessControlAllowOriginAddon

Enable cross-origin resource sharing in Meteor?

I'm trying to get a list of channels from my main application to an external angular app.
I've added https://github.com/stubailo/meteor-rest/blob/master/packages/rest/README.md to my main meteor app and now I can get the collection with a url as json format.
Now the problem comes when I try to http request from the external angular app.
Here's what I have in my main meteor app:
'use strict'
Meteor.publish('channels', function (index) {
return Channels.find({});
}, {
url: 'channels',
httpMethod: 'get'
});
and here's what I use to make the http request in the external angular app:
// Simple GET request example:
$http.get('http://example.com/channels').then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
console.log('success');
console.log(response);
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log('error');
console.log(response);
});
But what I get in response is an error:
XMLHttpRequest cannot load http://example.com/channels. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
What can I do to fix this?
From the documentation on the meteor-rest package:
If you would like to use your API from the client side of a different app, you need to return a special header. You can do this by hooking into a method on the simple:json-routes package, like so:
// Enable cross origin requests for all endpoints
JsonRoutes.setResponseHeaders({
"Cache-Control": "no-store",
"Pragma": "no-cache",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With"
});

Categories

Resources