Issuing 2 API requests in same session?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Issuing 2 API requests in same session?

Daniel Barrett-3
I'm trying to log into a MediaWiki 1.28 site using the API and a standalone PHP script, but it keeps failing with the error "invalid token." I can successfully retrieve a login token:

$tokenRequest = array(
  'action' => 'query',
  'format' => 'json',
  'meta' => 'tokens',
  'type' => 'login',
);

But when I issue my "action=clientlogin" request, I always get the error "code=badtoken, info = invalid token":

$loginRequest = array(
  'action' => 'clientlogin',
  'format' => 'json',
  'logintoken' => $token,
  'loginreturnurl' => 'https://example.com/',
  'username' => $username,
  'password' => $password,
  'domain' => 'mydomain',
  'rememberMe' => 1,
);

I suspect the problem is that the two requests are not explicitly being made in the same session. That is, I'm not adding the header "Cookie: <session cookie>" to my second HTTP POST. How do I retrieve the session cookie after issuing my meta=tokens request so I can hand it to the client login request? In earlier versions of MediaWiki, I could get the cookie information from an API call, "action=login". This has been deprecated but I haven't seen any examples of the new way to do it, just generic instructions like "Clients should handle cookies to properly manage session state."

I'm not operating inside the MediaWiki codebase with its WebRequest, SessionManager, etc. classes -- this is a standalone script.  

Thank you,
DanB


_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Issuing 2 API requests in same session?

Betacommand
Most frameworks have a cookie jar session handling as part of the language. I dont program PHP myself, but it should have the generic cookie handling you're looking for.

On Fri, Jul 14, 2017 at 12:13 PM, Daniel Barrett <[hidden email]> wrote:
I'm trying to log into a MediaWiki 1.28 site using the API and a standalone PHP script, but it keeps failing with the error "invalid token." I can successfully retrieve a login token:

$tokenRequest = array(
  'action' => 'query',
  'format' => 'json',
  'meta' => 'tokens',
  'type' => 'login',
);

But when I issue my "action=clientlogin" request, I always get the error "code=badtoken, info = invalid token":

$loginRequest = array(
  'action' => 'clientlogin',
  'format' => 'json',
  'logintoken' => $token,
  'loginreturnurl' => 'https://example.com/',
  'username' => $username,
  'password' => $password,
  'domain' => 'mydomain',
  'rememberMe' => 1,
);

I suspect the problem is that the two requests are not explicitly being made in the same session. That is, I'm not adding the header "Cookie: <session cookie>" to my second HTTP POST. How do I retrieve the session cookie after issuing my meta=tokens request so I can hand it to the client login request? In earlier versions of MediaWiki, I could get the cookie information from an API call, "action=login". This has been deprecated but I haven't seen any examples of the new way to do it, just generic instructions like "Clients should handle cookies to properly manage session state."

I'm not operating inside the MediaWiki codebase with its WebRequest, SessionManager, etc. classes -- this is a standalone script.

Thank you,
DanB


_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api


_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Issuing 2 API requests in same session?

bawolff
In reply to this post by Daniel Barrett-3
You're correct the token is tied to the cookie value

How to do this is going to depend on how you are making HTTP requests.

If you are using PHP fopen, things are kind of complicated
$listOfHeaders = stream_get_meta_data( $fileHandle )['wrapper_data'];

gets you a list of headers. From there you you have to figure out
which one is the set-cookie header, and parse it.

Then when making the request, you have to add the cookie to the header
list in $options['http']['header'] where $options is the array fed to
stream_context_create().


If you are using the PHP curl extension:

You can get the various headers using the CURLOPT_HEADERFUNCTION callback option

You can set headers to send using the CURLOPT_HTTPHEADER option
------------------

There are examples for both curl and fopen in the includes/http
directory of MediaWiki. There are many php frameworks out there that
simplify all this, you may want to use one of those.

--
Brian

On Fri, Jul 14, 2017 at 4:13 PM, Daniel Barrett <[hidden email]> wrote:

> I'm trying to log into a MediaWiki 1.28 site using the API and a standalone PHP script, but it keeps failing with the error "invalid token." I can successfully retrieve a login token:
>
> $tokenRequest = array(
>   'action' => 'query',
>   'format' => 'json',
>   'meta' => 'tokens',
>   'type' => 'login',
> );
>
> But when I issue my "action=clientlogin" request, I always get the error "code=badtoken, info = invalid token":
>
> $loginRequest = array(
>   'action' => 'clientlogin',
>   'format' => 'json',
>   'logintoken' => $token,
>   'loginreturnurl' => 'https://example.com/',
>   'username' => $username,
>   'password' => $password,
>   'domain' => 'mydomain',
>   'rememberMe' => 1,
> );
>
> I suspect the problem is that the two requests are not explicitly being made in the same session. That is, I'm not adding the header "Cookie: <session cookie>" to my second HTTP POST. How do I retrieve the session cookie after issuing my meta=tokens request so I can hand it to the client login request? In earlier versions of MediaWiki, I could get the cookie information from an API call, "action=login". This has been deprecated but I haven't seen any examples of the new way to do it, just generic instructions like "Clients should handle cookies to properly manage session state."
>
> I'm not operating inside the MediaWiki codebase with its WebRequest, SessionManager, etc. classes -- this is a standalone script.
>
> Thank you,
> DanB
>
>
> _______________________________________________
> Mediawiki-api mailing list
> [hidden email]
> https://lists.wikimedia.org/mailman/listinfo/mediawiki-api

_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Issuing 2 API requests in same session?

Gergo Tisza
On Fri, Jul 14, 2017 at 6:51 PM, bawolff <[hidden email]> wrote:
If you are using the PHP curl extension:

You can get the various headers using the CURLOPT_HEADERFUNCTION callback option

You can set headers to send using the CURLOPT_HTTPHEADER option

If you are using curl (highly preferable), just set CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE to the same file (does not have to exist initially) for every request, and it will automatically handle cookies like a real browser would. Much more robust than trying to parse Set-Cookie headers yourself. 

_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Issuing 2 API requests in same session?

Gergo Tisza
Also if you are just doing this for testing, it might be worth looking into some friendly tool like httpie. [1] (Otherwise you'll probably want to use an existing library; [2] there are all kinds of edge cases in handling the API which take a bit of effort to reimplement.)


_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Issuing 2 API requests in same session?

Daniel Barrett-3
In reply to this post by bawolff
Thanks to all who offered advice on logging in via API over multiple requests in the same session. For posterity, here's what worked for a "post" function that preserved the session information.

/**
* Perform an HTTP post to the MediaWiki API
* @param array $data - associative array of MW API parameters
* @return associative array
*/
function post($data) {
  $jar = __DIR__ . '/cookies.txt';

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $this->url);
  curl_setopt($ch, CURLOPT_POST, TRUE);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_COOKIEJAR, $jar);
  curl_setopt($ch, CURLOPT_COOKIEFILE, $jar);

  $result = curl_exec($ch);
  curl_close($ch);
  return json_decode($result, true);
}

DanB


_______________________________________________
Mediawiki-api mailing list
[hidden email]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
Loading...