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
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 danb@vistaprint.com 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 Mediawiki-api@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
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 danb@vistaprint.com 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 Mediawiki-api@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
On Fri, Jul 14, 2017 at 6:51 PM, bawolff bawolff+wn@gmail.com 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.
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.)
[1] https://httpie.org/ [2] https://www.mediawiki.org/wiki/API:Client_code#PHP
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@lists.wikimedia.org