405 (Method Not Allowed) Error

Hi,

I am attempting to get a pure cloud auth token but receive this error, although I am sending a post request.

#Error 
OPTIONS https://login.mypurecloud.com/oauth/token 405 (Method Not Allowed)

#Javascript code
secret = "SECRET";
id = "ID";
var encodedData = window.btoa(id + ':' + secret);
var authorizationHeader = 'Basic ' + encodedData;

fetch('https://login.mypurecloud.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': authorizationHeader,
  },
  body: {
    'grant_type' : 'client_credentials'
  }
})
.then(console.log)

I also tried to do it via an implicit grant and I get a Sorry, PureCloud cannot authenticate you at this time. We did not recognize your redirect url. or
your client id may have expired or is incorrect error.

function getParameterByName(name) {
  name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  var regex = new RegExp("[\\#&]" + name + "=([^&#]*)"),
  results = regex.exec(location.hash);
  return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
const script = document.createElement("script");
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js";
script.async = true;
document.body.appendChild(script);

if(window.location.hash) {
    console.log(location.hash);
    var token = getParameterByName('access_token');
    console.log(token);

} else {
    var queryStringData = {
        response_type : "token",
        client_id : "CLIENT ID",
        redirect_uri : "http://localhost:3000"
    }

    window.location.replace("https://login.mypurecloud.com/oauth/authorize?" + jQuery.param(queryStringData));
}

Please advise. Any help would be appreciated. For the client id I am solely putting the client id not base encoding it with the secret key like we did for the client credentials grant.

As the error states, the OPTIONS method is not allowed on that endpoint. Your HTTP library should be configured so it doesn't send an OPTIONS preflight request.

The redirect URL must match what you have configured exactly. For example, http://localhost:3000 is different than http://localhost:3000/. Also be sure your client ID is free of typos.

You might want to look into using the JavaScript SDK. It has helpers for authenticating.

like we did for the client credentials grant.

If this code is in a browser, under no circumstances should you use client credentials. That would require you to share the client secret with the web application and end user, which means leaking the password for the credentials. If this is discovered to be done publicly, your oauth client will be revoked for security reasons. Client credentials must only be used in secure server-side or desktop applications that can handle the client secret securely.

Hi Tim,

Thank you for your prompt response. I just read the MDN documentation on CORS policy and the way to prevent a preflight request is to remove certain headers which I have done in order to make it a "simple request". However, my understanding from reading the PureCloud SDK documentation is I must include the Authorization header in order to authenticate with PureCloud however in that case my (and all other servers) will send the pre-flight request as per CORS policy because of that specific header.

Do you have any suggestions on being able to include the authorization information for purecloud to authenticate in a way where it is not included in the header of the request.

See my code below:

fetch('https://login.mypurecloud.com/oauth/token', {
      'host' : 'http://localhost:3000/',
      'method': 'POST',
      'headers': {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'Authorization': authorizationHeader, //Cors policy does not like this header being included
      },
      'body': {
        'grant_type' : 'client_credentials'
      },
         'mode' : 'cors',
    })
    .then(console.log)

Interestingly enough, if I move the authorization key value into the body for example, CORS policy will consider it a simple request and I avoid the preflight request but then your server expectedly gives me a 400 Bad request error as the authorization information is not where it is expected (in the body vs in the header).

Any guidance would be much appreciated.

EDIT: I checked on stack overflow and it seems that the only way to do this would be for the server to allow options pre-flight request. I am also not sure / confused how the four code samples on your OAUTH Client Credentials Login Flow page are able to include 'authorization' header without sending a pre-flight request. https://developer.mypurecloud.com/api/tutorials/oauth-client-credentials/?language=nodejs&step=1

So i was able to get it to work by strictly having my back end nodejs service make the call and using the provided nodejs code. The key thing and what I learned was to not have the browser/front end client make the request because browsers have to abide by CORS policy but servers don't. Thank you for the help @tim.smith . I hope this saves someone else a day's worth of time!

1 Like

The lack of CORS headers on the response to https://login.mypurecloud.com/oauth/token and rejection of the OPTIONS request are intentional because you you can't use auth code or client credentials grants from a browser. Client-side browser apps should only use the implicit grant, server side apps (web site back ends or services) should use the auth code grant for user logins and client credentials for non-user logins.

2 Likes

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.