Search code examples
javascriptajaxdialogibm-cloudibm-watson

POST call Unauthorized in bluemix dialog


I receive this error response when clicking the button:

"POST https://watson-api-explorer.mybluemix.net/dialog/api/v1/dialogs/c8e08780-b08b-4cdb-8b8c-ea118863fcd1/conversation 401 (Unauthorized)"

Here's my code:

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>

<body>
    <button onclick="makePostCall()">Click me</button>
    <script>
        makePostCall = function() {
            var username = "c0ae64ef-410a-4f74-b875-ef52dee90686";
            var password = "9K2q4byngzo7";
            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'https://watson-api-explorer.mybluemix.net/dialog/api/v1/dialogs/c8e08780-b08b-4cdb-8b8c-ea118863fcd1/conversation', true);
            //xhr.withCredentials = true;
            xhr.setRequestHeader('Access-Control-Allow-Origin', 'http://localhost:80');
            xhr.setRequestHeader('Access-Control-Allow-Credentials', '*');
            xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
            xhr.setRequestHeader('Access-Control-Allow-Headers', 'Content-Type', 'application/json', 'Authorization');
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + " " + password));
            xhr.send('{"query":{"match_all":{}}}');
        }
    </script>

</body>

</html>

Solution

  • First point you really shouldn't post your dialog service credentials in the code. Now that you have, I suggest you delete the service and get yourself a fresh set of credentials.

    Second point, because of browser domain cross site restrictions, your client side javascript should be invoking a proxy API in your own server. https://watson-api-explorer.mybluemix.net is the entry point into the swagger documentation, which can't be your application. You can use the swagger APIs either from the swagger client or from an application like curl, not from the browser based client of your own web application. Actually that is how the swagger application works, the application is on https://watson-api-explorer.mybluemix.net and it has proxy end points on https://watson-api-explorer.mybluemix.net

    You will need your own application entry points that act as proxies to the real url for the Dialog service API which has an entry point at https://gateway.watsonplatform.net/dialog/api

    You are passing in a dialog id into your proxy, so you must have obtained it somehow. There are two ways you could have done this. Either by creating it ala -

    curl -u "{username}":"{password}" -X POST  \
            --form [email protected] \
            --form name=templateName \
            "https://gateway.watsonplatform.net/dialog/api/v1/dialogs" 
    

    or by asking for a list of the dialogs ala -

     curl -u "{username}":"{password}" "https://gateway.watsonplatform.net/dialog/api/v1/dialogs"
    

    Both ways require you to provide the service credentials. So they should be ok.

    Once you have your architecture sorted the conversation API is

    curl -u "{username}":"{password}" \
       -X POST
       --form conversation_id={conversation_id}
       --form client_id={client_id}
       --form input="Hi Hello"
       "https://gateway.watsonplatform.net/dialog/api/v1/dialogs/{dialog_id}/conversation"
    

    All the sample curls invocations of the service are available in the documentation - https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/dialog/api/v1/