1

I am creating a web react web service that needs IBM watson personality insight service. documented here

This is my request

var test = "some string";
var myHeaders = new Headers();
myHeaders.append("authorization",config.ibmCredential);
myHeaders.append("Content-type", "text/plain");
myHeaders.append("Accept", "application/json");
myHeaders.append("Access-Control-Allow-Origin","*");
var myRequest = { method: 'POST', headers: myHeaders, body: test}

and I call it via:

async postData() {
const data = await fetch(`${config.ibmURL}`,myRequest);

and the result Firefox console gives me is:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://gateway.watsonplatform.net/personality-insights/api/v3/profile?version=2018-10-20. (Reason: missing token ‘access-control-allow-origin’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).

I also tried to obtain a token to use instead of sending credentials. However, Firefox consoles only provided me with this, which I don't know what it is nor how to use it.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://gateway.watsonplatform.net/authorization/api/v1/token?url=https://gateway.watsonplatform.net/personality-insights/api. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

*Note that both of these requests work well with Postman

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Tran Triet
  • 1,257
  • 2
  • 16
  • 34
  • 1
    Not all IBM Watson services support getting cross-origin requests from frontend JavaScript code running in browsers. But see the answer at https://stackoverflow.com/questions/43105146/how-to-call-ibm-watson-services-from-javascript/43106268#43106268 for how-to info about how you can get those requests to work by making them through a public CORS proxy. – sideshowbarker Jul 11 '17 at 10:30
  • 2
    The first error message cited in the question indicates that your frontend JavaScript code is setting an 'access-control-allow-origin' header. You don’t want to do that. That header is a *response* headers that servers need to send. So remove that from your frontend code and see if it works. But if it doesn’t, you can’t fix whatever problem you’re having by trying to set that header from your frontend code. – sideshowbarker Jul 11 '17 at 10:33
  • The reason it works in Postman is that Postman won’t block you from seeing the response if it doesn’t include the Access-Control-Allow-Origin response header. But browsers will block your frontend JavaScript code from accessing an response cross-origin if it doesn’t include that header. That’s how CORS works – sideshowbarker Jul 11 '17 at 10:35
  • Thank you for the explanation on CORS. But how do I get it to work with IBM personality? It says it 'supports' CORS, does that mean I can still use the service without a proxy server? I saw firefox sent the preflight, but I don't know how to obtain the token. They only show how to using "curl", but I'm writing in javascript, how do I convert the curl syntax to javascript? – Tran Triet Jul 12 '17 at 03:05
  • 1
    I’ve never used the Personality Insights service but I see the docs at https://www.ibm.com/watson/developercloud/doc/personality-insights/release-notes.html#June2016b say it does support CORS, and I see at https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack#watson-developer-cloud-webpack-example there’s example code you can start from. So you probably want to try setting up that example code and modifying it to what you need – sideshowbarker Jul 12 '17 at 04:31

1 Answers1

1

sideshowbarker comments are correct - you do not want to set the Access-Control-Allow-Origin header; that's true of all CORS requests.

Additionally, for Watson CORS requests, you cannot set an Authorization header, because this would leak your private credentials to your end users.

Instead, you must use Auth Tokens, which requires a small amount of server-side code.

Your server-side code makes a request with your private credentials and then obtains a temporary auth token that can be exposed to clients. The client sets it in either an X-Watson-Authorization-Token header or else a watson-token querystring param.

Note that the token comes url-encoded, so you should take care not to double-encode it if using it in a querystring.

In general, I'd recommend using the SDK when possible - you can combine the webpack and Persionality Insights examples to achieve your goal of using Personality Insights from client-side code.

Nathan Friedly
  • 7,837
  • 3
  • 42
  • 59