0

I am trying to get a session token from the one login api using a cross-domain request with javascript and chrome. The request fails with the following message:

Failed to load https://api.us.onelogin.com/api/1/login/auth: Response to 
preflight request doesn't pass access control check: No 'Access-Control- 
Allow-Origin' header is present on the requested resource. Origin ' 
<my_server_url>' is therefore not allowed access. The response had HTTP 
status code 404.

The code used to make the request is the following:

function get_session_token(user,pwd,domain)
{

  var method = "POST";
  var url = "https://api.us.onelogin.com/api/1/login/auth";

  var xhr = new XMLHttpRequest();
  xhr.withCredentials = True

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      //response logic here...
   }
  }

  xhr.open(method, url, true);

  xhr.setRequestHeader("Content-Type", "application/json");
  xhr.setRequestHeader("Authentication", "Bearer "+bearer);
  xhr.setRequestHeader("Custom-Allowed-Origin-Header-1", "<my_server_url>");

  body = {
    "username_or_email": user, 
    "password": pwd, 
    "subdomain": domain
  }

  xhr.send(JSON.stringify(body));
}

The request works correctly from Postman. Any idea on how to solve it?

Zoolgoth
  • 3
  • 2
  • Did you perform some [research](https://stackoverflow.com/questions/20819196/rails-responds-with-404-on-cors-preflight-options-request) on Stackoverflow? – Jeroen Heier Jun 22 '18 at 18:16
  • @Jeroen Heier I do not see how your answer is relevant. My question concerns OneLogin Api. Did you read [the releative documentation](https://developers.onelogin.com/api-docs/1/login-page/create-session-login-token) ? I am not asking how to setup CORS server side and the proxy solution in one of the comments you linked would cause problems with the second step of the authentication, when the cookie is setup . According to OneLogin documentation the proxy is not necessary. – Zoolgoth Jun 24 '18 at 11:03

1 Answers1

0

I won't dive into the details of "WHY CORS?" (because of cross-site scripting attacks) But if you want to know why the browser rejects this call (that error is generated by your browser, not OneLogin) just google CORS.

The answer is that when you first request the login token from OneLogin you have to provide the web page you're making the Javascript call from.

https://developers.onelogin.com/api-docs/1/login-page/create-session-login-token - specifically the Custom-Allowed-Origin-Header-1 parameter.

By setting this to the hostname your webpage is making the Javascript request from, you instruct OneLogin to properly let the browser know it's okay that you're making a Javascript call across domains to get a resource.

Set that to the domain your webpage is on and it should work.

John Offenhartz
  • 831
  • 8
  • 11
  • Seriously, thanks for the lesson. Except you did not read in a script of 10 lines xhr.setRequestHeader("Custom-Allowed-Origin-Header-1", "") and this is exactly what I am doing.. (where obviously is the actual domain of the webpage.) Now, google preflight and how to handle correctly the OPTION request from server side. – Zoolgoth Jun 26 '18 at 09:11
  • that said, I think OneLogin enables CORS request for the https://.onelogin.com/session_via_api_token endpoint but not for getting the session token. Indeed, if you get the session token without CORS (through middle layer or simply Postman) but specifying the Custom-Allowed-Origin-Header-1 when doing so, CORS works correctly. Maybe this should be specified in the documentation, if that is the case. – Zoolgoth Jun 26 '18 at 09:44
  • Sorry I wasn't clearer: That first call must be made via the back-end to your web-page.then the subsequent call to exchange the token can be made via an XHR request, Your browser does not allow Post requests to our APIs via javascript. The only exception to this is the call to exchange the login token, which must be made via the front end (in your case using XHR) so the proper cookies can be set on the client. Because of CORS enforcement by the browser, this is true of all POST requests to cross-domain APIs (not just OneLogin's APIs). – John Offenhartz Jun 27 '18 at 12:46
  • Yes, and thanks for this second response. To be fair, the pictures in https://developers.onelogin.com/api-docs/1/login-page/login-user-via-api are quite clear about this, so just wanted confirmation – Zoolgoth Jun 28 '18 at 15:23
  • @JohnOffenhartz Hi John, could you please tell how to get a token when I request this: "https://api.us.onelogin.com/auth/oauth2/token", the browser generates a pre-flight OPTIONS request and it fails with "404 Not Found" (Response to preflight request doesn't pass access control check)? – Dmitry Stril Jul 30 '18 at 09:13
  • 2
    @DmitryStril - That call is never going to work via JavaScript because a) Your browser considers that a cross-site call and b) OneLogin doesn't support CORS for those calls. I'll add that it's a really bad idea to include a clientID & secret in browser call! – John Offenhartz Aug 01 '18 at 19:37