Back to oDesk.com » Love the way you work.

Welcome to the oDesk Community! Connect here with fellow clients, contractors, and oDesk staff. Please review our Usage Policy.

An error while using Token-based authentication

Hello!

I'm building a shell script on PHP, which should connect to oDesk periodically and fetch the ernings of my company and import it to our accounting software.

I had downloaded a library from developers.odesk.com - oDeskAPI.lib.php v 0.3.1.
Some monthes ago I'd made some drafts of the script and was able to receive the data from oDesk.

Today I tried to finish the script, but now I'm facing the exception, which comes from oDeskAPI.lib.php:
API return code - 404. Can not get token.

I began to hack the library and debug the situation. Firstly, I'd thought that something wrong with my keys. I'd dropped the old keys and created the new today - this didn't help. The issue happens when I execute oDeskAPI->auth() method.

Looked inside the library, I'd found 4 steps there:
1. login
2. get frob
3. authorize
4. get token

...so, the issue happens on the final step.
4th step tries to execute self::get_api_token() method and throws an exception.

Here is some dumps:
CURL does the GET request to URL like this:
https://www.odesk.com/api/auth/v1/keys/tokens.xml?api_key=b94**************************f2b&api_sig=2******************************0&frob=f******************************9

..and receives:

array(
['response'] => '<?xml version="1.0" encoding="utf-8"?>
1359675914404404No tokens found
'
['info'] =>
array(
['url'] => 'https://www.odesk.com/api/auth/v1/keys/tokens.xml?api_key=b94**************************f2b&api_sig=2******************************0&frob=f******************************9'
['content_type'] => 'text/xml; charset=utf-8'
['http_code'] => 404
['header_size'] => 472
['request_size'] => 450
['filetime'] => '-1'
['ssl_verify_result'] => 20
['redirect_count'] => 0
['total_time'] => 0.437
['namelookup_time'] => 0
['connect_time'] => 0.062
['pretransfer_time'] => 0.187
['size_upload'] => 0
['size_download'] => 151
['speed_download'] => 345
['speed_upload'] => 0
['download_content_length'] => 151
['upload_content_length'] => 0
['starttransfer_time'] => 0.437
['redirect_time'] => 0
['certinfo'] =>
)
['error'] =>
['header'] =>
'<?xml version="1.0" encoding="utf-8"?>
1359675914404404No tokens found
'
['body'] =>
)

My PHP Script looks like this:

<?php
require "lib/oDeskAPI.lib.php";
$url = "https://www.odesk.com/gds/finreports/v2/provider_companies/".COMPANY_REFERENCE."/earnings";
try {
$api = new oDeskAPI(API_SECRET, API_KEY);
/* Doing an authorization */
$api->option('mode', 'nonweb');
$api->option('verify_ssl', FALSE);
$api->option('cookie_file', 'C:/temp/cookies.txt');
$token = $api->auth(ACCOUNT_NAME, ACCOUNT_PASSWORD);
/* Sending a request */

} catch (Exception $e) {
echo '

'; echo 'Error: '.$e->getMessage()."\n"; echo 'Trace: '.$e->getTraceAsString(); echo '

';
}

I wonder - is that type of authorization supported? Has something changes from the times of Nov...Dec 2012??

Thanks,
Andrey

Vote Result

----------
Score: 0.0, Votes: 0
Hello Andrey,please check

Hello Andrey,

please check this part of documentation (section 'Get Token'). You should use POST, instead of GET.

I would suppose that you had managed to login after first download of library, a token was saved locally and after modifications you was able to get data using active token. And after token expiration, your modified library had tried to get a new token, as a result the process has failed. This is one of possible scenarios.
Anyway, I would suggest either re-download library or fix your current one according to your needs - but use POST, instead of GET for getting token.

Hello Maksym! I'd changed the

Hello Maksym!

I'd changed the request type to POST (in oDeskAPI->get_api_token() method, line 244) to this URL:
https://www.odesk.com/api/auth/v1/keys/tokens.xml

...but still receive the same XML and 404 status code.

As for this:
> Anyway, I would suggest either re-download library
Do you mean that I need to re-download oDeskAPI.lib.php library?
I'd gotten my copy from http://developers.odesk.com/w/page/12363997/API%20Libraries

Thanks,
Andrey Miroshnichenko

Yes, I meant - having an

Yes, I meant - having an official library is better than modified one.

Please, try it. If you still have troubles with your key, do not hesitate to contact apisupport@.

Hello Maksym! As I understood

Hello Maksym!

As I understood - you're the author of the library.
The latest library (I do mean this one which I was able to find: http://developers.odesk.com/w/page/12363997/API%20Libraries - and the lib in fact: http://developers.odesk.com/f/oDeskAPI.lib.php) is dated to 8.10.2011 (more then 1.5 years ago).

oDesk has changed some names into its forms, also probably the documentation has changes since these times.

So, (the second solution, which came to me after the fisrt Smile):
on line 97 (oDeskAPI->auth() method) change this:

self::send_request(self::URL_LOGIN . self::merge_params_to_uri(null, array('login' => $user, 'password' => $pass, 'action' => 'login'), FALSE), 'post');

to

self::send_request(self::URL_LOGIN . self::merge_params_to_uri(null, array('username' => $user, 'password' => $pass, 'action' => 'login'), FALSE), 'post');

And the first solution is step-by-step regarding the tutorial (my diff-file):

--- oDeskAPI.lib.php Mon Feb 4 23:12:33 2013
+++ new_oDeskAPI.lib.php Tue Feb 5 00:36:12 2013
@@ -94,7 +94,7 @@ final class oDeskAPI {
} else if (self::$mode === 'nonweb') {
// authorize nonweb application
// 1. login
- self::send_request(self::URL_LOGIN . self::merge_params_to_uri(null, array('login' => $user, 'password' => $pass, 'action' => 'login'), FALSE), 'post');
+ //self::send_request(self::URL_LOGIN . self::merge_params_to_uri(null, array('login' => $user, 'password' => $pass, 'action' => 'login'), FALSE), 'post');

// 2. get frob
$data = self::send_request(self::URL_FROBS . self::get_api_keys_uri($api_sig), 'post');
@@ -105,7 +105,10 @@ final class oDeskAPI {

// 3. authorize
$api_sig = self::calc_api_sig(self::$secret, array('frob' => $frob));
- self::send_request(self::URL_AUTH . self::merge_params_to_uri(self::get_api_keys_uri($api_sig), array('do' => 'agree', 'frob' => $frob)), 'post');
+ $auth_url = self::URL_AUTH . self::merge_params_to_uri(self::get_api_keys_uri($api_sig), array('do' => 'agree', 'frob' => $frob));
+ self::send_request($auth_url, 'post');
+ // 3.1 Login
+ self::send_request(self::URL_LOGIN . self::merge_params_to_uri('?redir='.urlencode($auth_url), array( 'username' => $user, 'password' => $pass, 'remember_me' => 0), FALSE), 'post');

// 4. get token
self::$api_token = self::get_api_token($frob);

Andrey,thank you for your

Andrey,

thank you for your comprehensive post.

oDesk have to support both field names for interoperability/backwardcompatibility. I will clearify this moment.

p.s. btw, 3.1 can't be after 3, because to authorize app you should login at first.

Andrey, I have re-downloaded

Andrey,

I have re-downloaded the library and run a test app, and managed to get correct data.
So, it looks the root of issue somewhere deeper. Might it be that your app creates cookies or conflicts somehow with that field name?

Have you tried to download a fresh example and run it together with fresh-downloaded library?

Please, let us know if you still have an issue

Try changing your auth type.

Try changing your auth type. It should work.

Hello Mar! I'd resoved the

Hello Mar!

I'd resoved the problem into my previous post.
Thank you Smile

No tokens found

The same problem here.

I'm traing to obtain the access token using url:
https://www.odesk.com/api/auth/v1/keys/tokens.json?api_key=f120d4d08ba2a36aceb0d0cae3e5ef18&api_sig=24e5b040025b099b4a765207ed9bb471&frob=aeae311c1e0f5baaee402af553f01ddf

I tried to send the params by get and by post methods, result is always the same:
"{"server_time":1362747456,"error":{"status":404,"code":404,"message":"No tokens found"}}"

I'm not using the library. I wrote my own code based on this documentation:
http://developers.odesk.com/w/page/38106635/Authentication%20using%20Token

hello Jakub, I would

hello Jakub,

I would recommend to take one of examples, test it and compare with your library to find issue in your code.