node-sdk: Assistant2 CORS policy error. Access to XMLHttpRequest: No 'Access-Control-Allow-Origin' header.

Hi, Iโ€™m trying to use the Assistant2 APIs inside my Web Application (Angular CLI project) with the suggested Webpack Configuration .

I followed the official docs to use the APIs on pure Client scenario, as described here:

Overview

I want to authenticate by iam_apikey, so my configuration is something like this:

import * as Assistant2 from 'ibm-watson/assistant/v2';

const assistant = new Assistant2({
  version: '2019-02-28',
  iam_apikey: '****************',
  url: 'https://gateway-lon.watsonplatform.net/assistant/api'
});

assistant.createSession({
    assistant_id: '***************'
})
.then(res => {
    console.log(JSON.stringify(res, null, 2));
 })
 .catch(err => {
   console.log(err);
 });

Debugging at runtime, after the Assistant2 initialization and before the createSession method execution, the assistant object looks like this:

assistant :  {
     tokenManager: {
          iamApikey: '****************',
          iamUrl: 'https://iam.cloud.ibm.com/identity/token',
          tokenInfo: { }
      },
     _options: {
          iam_apikey: '****************',
          qs: {
                version: '2019-02-28'
           },
          rejectUnauthorized: true,
          url: 'https://gateway-lon.watsonplatform.net/assistant/api',
          version: '2019-02-28'
     }
}

But executing the createSession method, I get the following errors:

Refused to set unsafe header "Accept-Encoding" (xhr.js:126).

Access to XMLHttpRequest at 'https://iam.cloud.ibm.com/identity/token' from origin 'http://localhost:5001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

It seems that the IAM server that should generate the access token is not working. As quoted here by @germanattanasio .

Expected behavior The Assistant2 support CORS so I expected to simply call the APIs authenticating by the iam_apikey.

Actual behavior CORS policy error.

SDK Version ibm-watson: 4.1.1

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 4
  • Comments: 27 (14 by maintainers)

Most upvoted comments

Changes are being tested in dev I expect them to be in staging next week and hopefully prod a day or two after staging

The node-sdk can be used in a browser but not the IAM service. You are getting an error because you are trying to use your apikey in the constructor and the SDK is trying to get a token with it.

The recommendation is to have that interaction between <apikey> and <access_token> in the server-side.

The node-sdk will then use the access_token.

This is a security feature. The fact that the node-sdk accepts an apikey is just for convenience since we do the token exchange behind scenes

The changes to support CORS are now in production ๐ŸŽ‰

Still in dev. Something with ingress came up so they are working on that first

๐ŸŽ‰ This issue has been resolved in version 4.3.4 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

@npacucci #925 should solve at least that casting issue

Glad that this works! In the short term, I think we should at least be able to add additional properties to the constructor parameters type so that you donโ€™t need to cast as any. Iโ€™ll post that fix in the next week or so.

Hi guys, the spell works fine as workaround! I had to cast the Options constructor object to any, and also serialize the input data.

Like this:

this.assistant = new Assistant({
                        version: this.version,
                        url: this.url,
                        iam_access_token: accessToken,
                        transformRequest: [(data, headers) => {
                            //Bugfix User-Agent Access-Control-Allow-Headers error
                            if (headers != null) {
                                delete headers['User-Agent'];
                            }
                            
                            if (data != null) {
                                return JSON.stringify(data);
                            }
                            
                            return data;
                        }]
                    } as any);

But now it works fine on cross browser ๐Ÿค“

@germanattanasio @npacucci What is the status of this issue?

Ohhh Thatโ€™s a problem on our side @npacucci. Let me work on it and get back to you.