Cookie set by Flask app sent but not stored - javascript

I have a backend Flask app running on localhost:3000 and a React front-end app running on localhost:5000. In my backend app I am using Flask's 'Response.set_cookie' to set a cookie:
resp = make_response({}, 200)
resp.set_cookie('my_cookie_name', 'my_val', max_age=604800, domain='127.0.0.1', samesite='Lax', secure=None, httponly=None)
I am also allowing cross-origin for all responses in my flask app as follows:
# Child class of Flask to override some features
class TailoredFlask(Flask):
# Override make_response
def make_response(self, rv):
# Call default version from partent
resp = super().make_response(rv)
# Add CORS header to every response
resp.headers["Access-Control-Allow-Origin"] = "*"
resp.headers["Access-Control-Allow-Methods"] = "GET,POST,OPTIONS,HEAD"
resp.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization"
return resp
My client accesses my flask cookie endpoint with a call to fetch.
In the Chrome dev tools I can see that the cookie is sent with the HTTP response from my backend. It is visible when on the Network->Cookies tab when I select the request to my backend. However, if I go to the Application tab in the dev tools, my cookie is not there.
It seems like chrome is silently discarding my cookie. I have seen several simiar issues here on SO but none of them seem to explain what is going on or provide a solution to my issue.
I'm also confused about the cookie options. There is a 'domain' option which I've read is to allow cross domain operation for the cookie. However, everything is running on localhost so I feel that I shouldn't need this unless the port is causing issues. However, I have also read that the port should not be included in the cookie 'domain' field.
If anyone can help to explain this to me I would greatly appreciate it because I'm just going round in circles with this stuff.
One more thing to note: I am pointing the browser at 'localhost', but the API call to my backend and the cookie domain both use '127.0.0.1', since I've read elsewhere that the 'domain' field must have at least two dots in it. (I don't have a choice in the browser URL since I am using AWS cognito login UI to redirect to my app after login. Cognito allows http for 'localhost', but only allows https for '127.0.0.1' so I have to use 'localhost' for development.) Could the missmatch between the browser url and cookie domain be causing this issue? Or is there something else that I'm missing?

Ok, so I think I now understand what's going on here, although I don't think there's a fix for my specific problem. As described in this thread browsers (including Chrome) will not allow a domian of 'localhost' within a cookie (I just wish there was a message in the console or something to indicate why the cookie is not being saved, rather than a silent fail!)
There are various suggestions for workarounds, such as using '.app.localhost' to access the application. Unfortunately this is not an option for me as I am redirecting to my front-end app from AWS Cognito, and the only domain that is supported with HTTP (rather than HTTPS) is 'localhost'. Variants such as '.app.localhost' or '127.0.0.1' are not allowed.

Related

Socket.io and express app not connecting due to CORS error: “The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*'”

I'm slowly losing my mind over a very stupid issue I'm having.
I have a socket.io/express app uploaded to Digital Ocean as a Docker setup.
To allow https, I am using caddy as part of my Docker setup to allow for automatic https.
I've been trying to connect to this setup via my domain and from my local React app that lives on localhost:3000. But I am constantly getting the following error:
Access to XMLHttpRequest at 'https://mediaserver.domain.dev/socket.io/?EIO=3&transport=polling&t=N5BXNK2' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
I know there have been a lot of SO questions about this before and believe me when I say I tried almost all of them.
I tried changing the options of the cors middleware
I tried adding my own middleware and setting headers specifically
I tried using localhost:3000 as origin
...
But nothing seems to work. I have currently no idea what I can still do to fix this.
So any help would be welcome.
My docker-compose file looks as follows:
version: '3.6'
services:
media-server:
build:
dockerfile: Dockerfile
context: ./
ports:
- "8080:5000"
expose:
- "5000"
caddy:
image: abiosoft/caddy:0.11.0
depends_on:
- "media-server"
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /root/Caddyfile:/etc/Caddyfile
- /root/.caddy:/root/.caddy
My Caddyfile is as follows:
https://mediaserver.domain.dev {
proxy / http://media-server:8080 {
websocket
transparent
}
cors
}
And my server setup looks as follows:
import cors from 'cors';
import express from 'express';
import socket from 'socket.io';
import { intialiseWebSocketConnection } from './socketio';
const app = express();
app.use(cors());
const server = app.listen(5000, function () {
console.log('Server is connectedd on *:5000');
});
const io = socket.listen(server);
intialiseWebSocketConnection(io);
You are attempting to make a cross-origin request with the credentials flag set and the Access-Control-Allow-Origin set to any (*). This is not allowed for security reasons. There are two ways to solve the problem. If you don't need to send credentials make sure the credentials flag is false. That is, if you are using an XMLHttpRequest make sure withCredentials is not true (it is false by default). If you are using the Fetch API make sure Request.credentials is set to "omit".
If you do need to send credentials for some reason, you have to set the Access-Control-Allow-Origin in your server's response to the origin from where you are sending requests to the server and not to any (*).
To figure out what your origin is just check to what the Origin header is set to in the requests you send to the server.
By default cors() sets the Access-Control-Allow-Origin to *. Try changing it to:
cors({
origin: "http://localhost:3000",
credentials: true
});
Also note Chrome does not support localhost as an origin. To get around that you can start Chrome with the --disable-web-security flag during development.
There's a simple way to bypass CORS errors for socket.io connections. By default socket.io starts each connection with several regular http calls. If things go well, it converts to a webSocket transport (and runs socket.io over the webSocket transport). Those initial http calls are subject to CORs restrictions.
But, if you tell socket.io to just start out with the webSocket transport right away, then you are not subject to CORs restrictions. You can do that in the client by doing this:
const socket = io({transports: ['websocket']});
Even though a webSocket connection always starts with one http request, that particular http request (with the appropriate upgrade header set is not subject to CORs restrictions.
The only downside to this (that I'm aware of) is that your code would not run in a browser that does not support webSockets. That would be a really, really old browser. Even IE10 (released in 2012) supports webSockets and all modern browsers have supported them since at least 2013. I'm actually not quite sure why socket.io still has their http polling as the default as it's far less efficient on the network to start out every connection. Anyway, you can easily bypass it with io({transports: ['websocket']});.

Access-Control-Allow-Origin is not * but Chrome insists it is (after upgrading apollo-server)

There were some features I wanted from apollo-server and spent some time refactoring my code to it (was previously using express-graphql). The only problem now is a "CORS" problem between my web app (using apollo-client) for authenticated requests. I recall having this problem as well back in version 1.x, and spent a lot of time wrestling with it, but my previous solution does not work in 2.x and would greatly appreciate some help for anyone who has managed to get this to work.
my webapp is hosted on localhost:8081
my server is hosted on localhost:4000
Following their code verbatim from here, I have the following:
Client code
const client = new ApolloClient({
link: createHttpLink({
uri: 'http://localhost:4000/graphql',
credentials: 'include'
})
})
Server code
// Initializing express app code
var app = ....
// Using cors
app.use(cors({
credentials: true,
origin: 'http://localhost:8081',
}));
// Apollo Server create and apply middleware
var apolloServer = new ApolloServer({ ... });
apolloServer.applyMiddleware({ app })
When the client queries the backend via. apollo-client, I get the following error in Chrome:
Yet in my server code, I am explicitly setting the origin. When I inspect the network request in console, I get a contradictory story as well as Access-Control-Allow-Origin explicitly is set to http://localhost:8081
I don't encounter this problem when using Insomnia to query my backend server and get the expected results. Does anyone have any experience setting up apollo on client and server on localhost and successfully authenticating?
I'm actually just dumb. I was looking at the wrong response, sideshowbarker was onto it, apollo-server-v2 automatically overrides CORS and sets the Access-Control-Allow-Origin header to * by default. Even if your express app specifies CORS and you apply that as a middleware to the apollo-server, this setting will be overridden for GraphQL routes. If anyone faces this problem, hopefully this'll save some time:
https://github.com/apollographql/apollo-server/issues/1142
You can now specify CORS explicitly for apollo-server in its applyMiddleware method:
https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2

I am getting CORS issue in Angular 5 app even though i get response from the server [duplicate]

This question already has answers here:
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 4 years ago.
I am using Angular 5 in my ionic app. I am trying to call a endpoint from my code
ngOnInit(): void {
//Called after the constructor, initializing input properties, and the first call to ngOnChanges.
//Add 'implements OnInit' to the class.
this.httpClient.get('https://abc-66b76.cloudfunctions.net/getBillNo', {
headers: {
'Access-Control-Allow-Origin': '*'
}
}).subscribe(data => {
console.log('firebase bill No: ', data);
this.bill.billNo = data.billNo;
})
}
When my page loads the above code is called and in chrome browser console i get the below error:
Failed to load https://abc-66b76.cloudfunctions.net/getBillNo: 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:8100' is therefore not allowed access.
However if i check my network tab in my chrome browser i can see that it has hit the server and has got the response.
Can anyone help me resolve this.
My Backend is firebase functions.
There's nothing to do in your Angular code. To make it working you need to either
Host your Angular code in https://abc-66b76.cloudfunctions.net (port 443) along with your backend
or
You need to allow your Angular hosted origin (in your case http://localhost:8100) in backend's Access-Control-Allow-Origin header (or * to allow all origin). Modern browsers verifies this and blocks requests in case this header is not present when cross-origin requests are performed for security considerations.
The way you set this header depends on your backend programming language.
if you use NodeJS + express
var cors = require('cors')
var app = express()
app.use(cors())
If the backend is not under your control, You can also tell your browser to ignore doing it.
Each browser would have a way to do it.
For chrome, Start chrome browser with --disable-web-security command line param (kill all running chrome instance).
A simple chrome extension can be used to do the magic (read its instructions) https://chrome.google.com/webstore/detail/cors-toggle/jioikioepegflmdnbocfhgmpmopmjkim?hl=en
If you are going to provide the Angular app for public then you should consider Adding the header or have a proxy for the backend and make requests via proxy, since you can't force each users to disable web security.
You probably need to do a proxy server, to avoid CORS when call api from localhost in development environment, so nodejs is a simple approach to make it, I really recommend you this post, it's simple to understand and easy to follow.
https://codeburst.io/using-nodejs-as-a-proxy-for-angularjs-ajax-requests-8e5e94203e0d
I found the easiest way is to use the node.js package cors. The simplest usage is:
var cors = require('cors')
var app = express()
app.use(cors())
There are, of course, many ways to configure the behavior to your needs; the page linked above shows a number of examples.

How to solve 'Redirect has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header'?

I am working on an app using Vue js.
According to my setting I need to pass to a variable to my URL when setting change.
<!-- language: lang-js -->
$.get('http://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
But when my app hit on URL, it shows the following message.
Failed to load http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26: Redirect from 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26' to 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
In addition to what awd mentioned about getting the person responsible for the server to reconfigure (an impractical solution for local development) I use a change-origin chrome plugin like this:
Moesif Orign & CORS Changer (use to be free but now wants a work email address >_>)
Allow CORS: Access-Control-Allow-Origin
You can make your local dev server (ex: localhost:8080) to appear to be coming from 172.16.1.157:8002 or any other domain.
In case the 2nd plugin link breaks in the future or the plugin writer decides to capitalize off the fame of this thread, open your browser's
plugin marketplace and search "allow cors", there's going to be a
bunch of them.
Thanks all, I solved by this extension on chrome.
Allow CORS: Access-Control-Allow-Origin
If you have control over your server, you can use PHP:
<?PHP
header('Access-Control-Allow-Origin: *');
?>
Ask the person maintaining the server at http://172.16.1.157:8002/ to add your hostname to Access-Control-Allow-Origin hosts, the server should return a header similar to the following with the response-
Access-Control-Allow-Origin: yourhostname:port
Using npm:
To allow cross-origin requests install 'cors':
npm i cors
Add this in the server-side:
let cors = require("cors");
app.use(cors());
When you have this problem with Chrome, you don't need an Extension.
Start Chrome from the Console:
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Maybe you have to close all Tabs in Chrome and restart it.
I will assume that you're a front-end developer only and that you don't have access to the backend of the application (regarding the tags of the question).
Short answer on how to properly solve this in your case? You can't, you'll need somebody else.
What is this about?
You need to understand that CORS is a security thing, it's not just here to annoy you just for fun.
It's purpose is to mainly prevent the usage of a (malicious) HTTP call from a non-whitelisted frontend to your backend with some critical mutation.
You could give a look to this YouTube video or any other one really, but I recommend a visual video because text-based explanation can be quite hard to understand.
You also need to understand that if you use Postman or any other tool to try your API call, you will not get the CORS issue. The reason being that those tools are not Web frontends but rather some server-based tools.
Hence, don't be surprised if something is working there but not in your Vue app, the context is different.
Now, how to solve this?
Depending of the framework used by your backend team, the syntax may be quite different but overall, you'll need to tell them to provide something like Access-Control-Allow-Origin: http://localhost:3000 (or any other port you'll be using).
PS: Using Access-Control-Allow-Origin: * would be quite risky because it would allow anybody to access it, hence why a stricter rule is recommended.
If you're using a service, like an API to send SMS, payment, some Google console or something else really, you'll need to allow your localhost in the dashboard of the service. Ask for credentials to your manager or Tech Lead.
If you have access to the backend, you could it yourself as shown here (ExpressJS in this example): https://flaviocopes.com/cors/
How to hack it in a dirty way?
If you're in a damn hurry and want to get something really dirty, you could use a lot of various hacks a listed in the other answers, here's a quick list:
use any extension who is able to create a middleware and forward the request to the backend (it will work because it's not directly coming from your frontend)
force your browser to disable CORS, not sure how this would actually solve the issue
use a proxy, if you're using Nuxt2, #nuxtjs/proxy is a popular one but any kind of proxy (even a real backend will do the job)
any other hack related somehow to the 3 listed above...
At the end, solving the CORS issue can be done quite fast and easily. You only need to communicate with your team or find something on your side (if you have access to the backend/admin dashboard of some service).
I heavily do recommend trying get it right from the beginning because it's related to security and that it may be forgotten down the road...
The approved answer to this question is not valid.
You need to set headers on your server-side code
app.use((req,res,next)=>{
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,PATCH,DELETE');
res.setHeader('Access-Control-Allow-Methods','Content-Type','Authorization');
next();
})
You can also try a chrome extension to add these headers automatically.
Hello If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
To add the CORS authorization to the header using Apache, simply add the following line inside either the <Directory>, <Location>, <Files> or <VirtualHost> sections of your server config (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess file:
Header set Access-Control-Allow-Origin "*"
And then restart apache.
Altering headers requires the use of mod_headers. Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled.
I had the same problem in my Vue.js and SpringBoot projects. If somebody work with spring you can add this code:
#Bean
public FilterRegistrationBean simpleCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// *** URL below needs to match the Vue client URL and port ***
config.setAllowedOrigins(Collections.singletonList("http://localhost:8080"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
I found solution in this article Build a Simple CRUD App with Spring Boot and Vue.js
You are making a request to external domain 172.16.1.157:8002/ from your local development server that is why it is giving cross origin exception.
Either you have to allow headers Access-Control-Allow-Origin:* in both frontend and backend or alternatively use this extension cors header toggle - chrome extension unless you host backend and frontend on the same domain.
Try running this command in your terminal and then test it again.
curl -H "origin: originHost" -v "RequestedResource"
Eg:
If my originHost equals https://localhost:8081/ and my RequestedResource equals https://example.com/
My command would be as below:
curl -H "origin: https://localhost:8081/" -v "https://example.com/"
If you can notice the following line then it should work for you.
< access-control-allow-origin: *
Hope this helps.
Do specify #CrossOrigin(origins = "http://localhost:8081")
in Controller class.
You can solve this temporarily by using the Firefox add-on, CORS Everywhere. Just open Firefox, press Ctrl+Shift+A , search the add-on and add it!
You won't believe this,
Make sure to add "." at the end of the "url"
I got a similar error with this code:
fetch(https://itunes.apple.com/search?term=jack+johnson)
.then( response => {
return response.json();
})
.then(data => {
console.log(data.results);
}).catch(error => console.log('Request failed:', error))
The error I got:
Access to fetch at 'https://itunes.apple.com/search?term=jack+johnson'
from origin 'http://127.0.0.1:5500' 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.
But I realized after a lot of research that the problem was that I did not copy the
right URL address from the iTunes API documentation.
It should have been
https://itunes.apple.com/search?term=jack+johnson.
not
https://itunes.apple.com/search?term=jack+johnson
Notice the dot at the end
There is a huge explanation about why the dot is important quoting issues about DNS and character encoding but the truth is you probably do not care. Try adding the dot it might work for you too.
When I added the "." everything worked like a charm.
I hope it works for you too.
install:
npm i cors
Then include cors():
app.get("/list",cors(),(req,res) =>{
});
In addition to the Berke Kaan Cetinkaya's answer.
If you have control over your server, you can do the following in ExpressJs:
app.use(function(req, res, next) {
// update to match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
https://enable-cors.org/server_expressjs.html
I tried this code,and that works for me.You can see the documentation in this link
var io = require("socket.io")(http, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
})
The reason that I came across this error was that I hadn't updated the path for different environments.
you have to customize security for your browser or allow permission through customizing security. (it is impractical for your local testing)
to know more about please go through the link.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
These errors may be caused due to follow reasons, ensure the following steps are followed. To connect the local host with the local virtual machine(host). Here, I'am connecting http://localhost:3001/ to the http://abc.test Steps to be followed:
1.We have to allow CORS, placing Access-Control-Allow-Origin: in header of request
may not work. Install a google extension which enables a CORS request.*
2.Make sure the credentials you provide in the request are valid.
3.Make sure the vagrant has been provisioned. Try vagrant up --provision this make the localhost connect to db of the homestead.
Try changing the content type of the header. header:{ 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8;application/json' }
this point is very important.
Another solution to this problem in a specific scenario :
If
AWS APIGW is your backend with authentication enabled and
authentication fails,
your browser may end up complaining about CORS even if CORS is enabled in APIGW. You also need to enable CORS for 4XX as follows
API:YourAPI > Resources > /YourResource > Actions > Enable CORS > Gateway Responses for yourAPI check Default 4XX
Authentication will still fail but it won't look like CORS is the root cause
$.get('https://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
Just put "https" .

how to call IBM Watson services from javascript

I am implementing a virtual agent using IBM Watson services. My application is developed using Jquery, Angular JS & Java.Currently i am calling the watson services from middle layer that is java. But i want to avoid that and call directly from javascript.When i call from javascript using XML Http request, i am getting CORS error.How to solve this?
Below is my code:
var username = "uid";
var password = "pwd";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url');
//xhr.withCredentials = true;
xhr.setRequestHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type, application/json, Authorization");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader('Access-Control-Allow-Credentials', '*');
xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
xhr.setRequestHeader('Content-Type', undefined);
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + " " + password));
xhr.send('"query":"hi"');
The IBM Watson services don’t yet support getting cross-origin requests from browser-based apps.
See the answer at Can't access IBM Watson API locally due to CORS on a Rails/AJAX App:
We don't support CORS, we are working on it but in your case Visual Recognition is not supported yet.
That implies some of the services support CORS but I guess the one you’ve tried isn’t one of them.
So other than what you say you’re doing now (accessing the services from your server-side Java layer instead), your only option to get at the services from JavaScript code running in a web app is, either set up your own server-side proxy with https://github.com/Rob--W/cors-anywhere or such, or send your requests through an open CORS proxy like https://cors-anywhere.herokuapp.com/ (though it’s unlikely you’ll want to do that in the case where your requests include any kind of authentication token that you don’t want to expose to the operator of a third-party proxy service).
The way such proxies works is, instead of using https://gateway.watsonplatform.net/some/api as the request URL that specify in your client-side JavaScript code, you instead specify the proxy URL, like https://cors-anywhere.herokuapp.com/https://gateway.watsonplatform.net/some/api, and the proxy sends the actual request to the service, gets back the response, and adds the needed Access-Control-Allow-Origin response header and other headers to it and passes it on.
So that response with the CORS headers included is what the browser sees.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has more details about how CORS works, but the main thing to know is that the browser is the CORS enforcement point. So in the case with the Watson services, the browser will actually get the response from the Watson API—you will be able to use devtools in the browser to see the response—but the browser will expose the response to your client-side JavaScript code only if the response includes the Access-Control-Allow-Origin response header to indicate the server that sent the response has opted in to receiving cross-origin requests from client-side JavaScript running in web apps.
So that’s why, regardless, all the xhr.setRequestHeader("Access-Control-Allow- lines in your XHR code snippet above need to just be removed—because Access-Control-Allow-* headers are response headers, not request headers; sending them in a request to a server has no effect on CORS, because as noted above, the browser’s the CORS enforcement point, not the server.
So it’s not the case that the server receives some request from a browser and says, OK I see this request has the right headers, so I’ll allow it. Instead the server allows all requests from browsers, just as it allows all requests from non-browser tools like your Java code or curl or Postman or whatever (as long as they are authenticated of course) and sends a response.
The difference is, when a non-browser-based app receives a response, it doesn’t refuse to let you access the response if it lacks the Access-Control-Allow-Origin header. But the browser does refuse to let your client-side JavaScript web-app code access the response if it lacks that.
You might also want to look at some of the Watson SDK's available on GitHub.
Some Watson services support CORS, others do not. However, when accessing over CORS, you must use an Auth Token rather than a username/password combination*.
This is a partial list of which services support CORS: https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack#important-notes
Here are a couple of examples using the Node.js SDK:
Webpack: https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack
Browserify: https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/browserify
And, a whole host of examples with the Speech JavaScript SDK:
https://watson-speech.mybluemix.net/
* There are a couple of services that use API keys rather than username/password combinations. In that case, you can use the API key directly from client-side code if the service supports CORS.
take a look at this tutorial on IBM developerWorks on using Watson's Question and Answer service -
http://www.ibm.com/developerworks/cloud/library/cl-watson-qaapi-app/index.html#N10229

Categories

Resources