Problems with 'generateToken'

6283
4
06-13-2013 02:43 PM
ChrisThomas4
New Contributor II
Hi! I'm new here. I'm also new to both Javascript and REST, so the answer to this might be relatively easy.

I'm having trouble with the generateToken request on https://www.arcgis.com/shared/rest/generateToken :
On my boss' dev machine, it is giving me a null response value after sending a 405 error, saying that I "don't have access to this function."
For my machine, see the PS note.

Please note that I have no idea what the 'referer' field is for, or why it's required; the API Docs fail to explain this, at least anywhere I can find. So therein could lie the rub, right there, but I wouldn't know any different.
Example version of my code follows:
var a = {
 "username": "thomas.chris.a",
 "password": "<mypassword>",
 "referer": "http://localhost:8080/MFF/"
};
$.ajax({
        type: 'POST',
 url: 'https://www.arcgis.com/sharing/rest/generateToken',
 data: a,
 contentType: 'application/json; charset=utf-8',
 dataType: 'json',
 processdata: true,
 success: function (resp)
 {
                // Now the function throws a JS exception, since resp is NULL and has no property 'd'
  var j = resp.d;
  var json1 = JSON.stringify(eval('(' + j + ')'));
  var json = eval('(' + json1 + ')');

  alert(json.token);
  callback(json.token);
 }
});

What I've tried:
For the "referer":

  • I tried using the URL of the testing version of the web app I am putting this into.

  • I also tried using "www.arcgis.com", & even the actual root of the real production version of the site.

  • I tried adding the client : "referer" field, despite knowing that that is the default value.

  • I tried taking the field out.

for passing the JSON:

  • I tried passing the JSON object in a string.

  • I tried parsing it into the url in parameters.

  • I tried taking out the "s around the parameter names (as I've seen in a few code examples from the Javascript API tutorials)

None of these attempts gave me any better results.
Other places I've looked for info:

  • The API Docs weren't much help, honestly. Smaller code snippets from different languages would be more helpful as examples than the nondescript examples on the Doc pages. Even just example JSON-formatted request params would help.

  • The code samples are mostly spread out over the APIs, and I couldn't find an explicitly REST request to generateToken anywhere.

  • Google didn't help much, either.

  • If someone did post a question like this in this forum, I couldn't find it. It may be in a different API version's sub-forum, but I wasn't about to muck about for hours trying to find it.

  • SO also helped zero, but I expected better results out of here, anyway.


I'm not sure what's wrong with this, but again, I'm not really sure exactly how all this works, yet. Teach me, Seymour. ^_^

Any help, suggestions, etc, would be appreciated greatly.

PS: On my dev machine, my jquery is breaking on the ajax call there and saying that "Access is denied," but fiddler reports no activity yet. I wish the dynamic js scripts from .NET were readable, so I could figure out why...
If I change the rest URL to use 'http:' instead of 'https:' my machine goes through with the request just fine and receives the expected response of "You need to use https."
This request with the exact same code worked on my boss' machine and gave us the 405 up there. It may be unrelated, but I always like giving the extra info just-in-case it's important.
0 Kudos
4 Replies
ChrisThomas4
New Contributor II
On the side-issue of my dev-machine not doing it right, there was an incompatibility between my particular version of IE and $.ajax calls in JQuery. I was using JQuery 1.4.1, and this issue was fixed in 1.8.1, so I updated it to 1.9.1 (if I'm going to update, I may as well just update all the way) and fixed that issue. Yay...

... But I still haven't gotten this request to go through. Any help will be met with cookies! (cookies subject to availability, not available in all areas, limited time offer, purchase necessary. see store for details)
But in all seriousness: I'm totally lost at this point. Is the API down or am I just plain doing it wrong?
0 Kudos
RichardWatson
Frequent Contributor
Does this help?

http://resources.arcgis.com/en/help/arcgis-online-network-analysis-rest-api/index.html#//02s50000000...

The referer field is used to prevent someone from using the token in conjunction with another website.  In other words, the token will only be accepted if the request is coming from the referer.

I suggest that you get this to work in the browser first and then worry about using JavaScript to do it with code.  I also suggest using Fiddler as well to that you can view the details of the response.  JSFIDDLE is another useful tool.  The idea is to first factor out all the complexity that you can and then add it back in layers.

I generate tokens all the time but I am using a local version of ArcGIS Server.  It appears that you are using ArcGIS Online.
0 Kudos
ChrisThomas4
New Contributor II
Thanks for the reply!
The link you posted does have some useful information on it that may help me get further. Parsing the parameters into the URL again using the format they provide in the example (!) on that page actually gets me a 200 response, but it's still going out over OPTIONS instead of POST, which the REST API insists upon, so my $.ajax().fail() still gets triggered.

As it turns out, jquery.ajax (and derivatives) send out an OPTIONS request instead of GET or POST whenever the request is going cross-domain. I'm obviously not working within the ArcGIS.com domain, so this simply will not do. In other words, I can't do it this way without using a rather convoluted approach.

I particularly like the sentence "you should use the appropriate client API [...] rather than do this directly via the REST API." I was specifically told to do this over REST, so I could learn how to deal with RESTful calls and what-have-you, but in the interest of just getting the thing working I might switch over to the JS API.

I'll keep posting back with whatever else I find.
0 Kudos
ChrisThomas4
New Contributor II
I ended up fixing this after all, although I can't remember what specifically caused it to work... I believe it was omitting the contentType field, for whatever reason. (I know that cross-domain requests are quite restricted, but don't recall if this was the reason.)
I do know that the cross-site nature of the call was making my IE8 not very happy, and Firefox, Chrome, Opera, Safari, and IE10 all worked with this code.

Anyway, here is the working code:
if ('withCredentials' in new XMLHttpRequest())
{
 /* supports cross-domain requests */
 $.support.cors = true;
 jqxhr = $.ajax(
 {
  url: "https://www.arcgis.com/sharing/rest/generateToken",
  type: "POST",
  data: {
   "username": "thomas.chris.a",
   "password": "<passwd here>",
   "expiration": 15,
   "referer": "http://localhost:8080/MFF/",
   "f": "json"
  },
  dataType: 'json'
 })
 .done(function (resp)
 {
  // in most browsers the response will be a json,
  // but in the event that it's a string (IE8-9) parse it.
  var json = (typeof resp === "String" ? $.parseJSON(resp) : resp);
  alert('token:' + json.token);
  callback();
 })
 .fail(function (xhr, txt, err)
 {
  alert('get token failed...');
 });
}
else
{
 // Either the browser doesn't support cross-domain at all,
 // or it's IE 8 or 9, and either way screw it. Use a real browser!
 alert('Unable to send request to ArcGIS: \n'
  + 'No CORS Support available in this browser!\n\n'
  + 'For better results, use a modern version \n'
  + 'of Firefox, Chrome, Opera, or Safari.');
 return;
}


I ended up restricting this particular functionality to any of the browsers which did work: that being any browser other than IE8/9. Thanks again, MS, for complicating things. The XDomainRequest type is what was screwing it up, after all. In my use-case, this is a piece of administrator functionality, so I'm allowed to make them use a browser that doesn't create its own web standards.
I'm not sure what I would have done if I needed to support IE8. I tried just about everything, including overriding the ajax transporters and a few other really ugly solutions, to get this to work, with no results in IE8. I was working on this request for a full, full-time week. So... I'm officially done supporting IE8, sorry Windows XP.

Thanks again for the help with that link! Hopefully posting this helps someone in the (distant)? future with this particular problem.
0 Kudos