Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Media Wiki API 'WrongToken'

by Random_Walk (Prior)
on May 24, 2018 at 08:11 UTC ( #1215136=perlquestion: print w/replies, xml ) Need Help??

Random_Walk has asked for the wisdom of the Perl Monks concerning the following question:

Good $localtime dear monks

I am using the MediaWiki API to create a page updating bot. I got through some problems getting my headers accepted thanks to help from bliako in the thread Rest::Client Headers not getting through. But now I still can't get wiki to accept the token it gives me. From some googling I understand you need to get a token, then hand it over along with a login request to link that token to a logged in session. This is all I'm trying here, but when I send the token I just got, I get the error 'WrongToken'

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use MIME::Base64; use JSON; use REST::Client; use Getopt::Long; use HTTP::Cookies; use URI::Escape; use Sys::Hostname; $|++; # Output buffering off my $wiki = 'https://wikihost'; my $api = '/mediawiki/api.php'; my $JSON = JSON->new->allow_nonref; # Create rest client and set some options my $client = REST::Client->new(); $client->setHost($wiki); my $ua = $client->getUseragent(); # Get the LWP User agent $ua->ssl_opts(verify_hostname => 0); my $cookie_jar = HTTP::Cookies->new( file => "/tmp/lwp_cookies.dat", autosave => 1, ignore_discard => 1, ); $ua->cookie_jar( $cookie_jar ); # Give the chap a cookie # First get a token. This works my $request = 'action=query&meta=tokens&type=login&format=json'; my $result = post($request); print Dumper $result; my $token = uri_escape( $result->{query}{tokens}{logintoken} ); print "URI Escaped Token: $token\n"; # Now we log in with that token. I've tried both the below requests $request = 'action=login&lgname=Marvin&lgpassword=ldiode&lgtoken=$toke +n&lgdomain=wikihost&format=json'; # $request = 'action=login&lgname=Marvin&lgpassword=ldiode&lgtoken=$to +ken&format=json'; $result = post($request); print Dumper $result; sub post { my $query = shift @_; $client->POST($api, $query, {'Content-type' => 'application/x-www- +form-urlencoded'}); if ( $client->responseCode() == 200 ) { return $JSON->decode( $client->responseContent() ); } else { print "Failed with code $client->responseCode()\n"; print Dumper $client->responseContent(); } }
And this is the output I get
./ $VAR1 = { 'batchcomplete' => '', 'query' => { 'tokens' => { 'logintoken' => '3de22ae8b84f7190 +35b25e69ae7b33655b06705a+\\' } } }; URI Escaped Token: 3de22ae8b84f719035b25e69ae7b33655b06705a%2B%5C $VAR1 = { 'login' => { 'result' => 'WrongToken' } };
Does anyone see any obvious errors in my code, or know the wiki API well enough to spot my error. The one thing I am not sure about is cookie handling. I have cargo culted that cookie setup from various example found on t'web. Should that cookie setup be sensible, or an I best to clear the cookie file between runs? Or have the cookies nothing to do with what's going on here?

Thanks in Advance,

Pereant, qui ante nos nostra dixerunt!

Replies are listed 'Best First'.
Re: Media Wiki API 'WrongToken'
by marto (Cardinal) on May 24, 2018 at 08:44 UTC

    From the docs:

    Important Note

    "You need to send the cookie obtained in the login phase when you call the api with the "tokens" action"

    Take a look at the REST::Client documentation, specifically the useragent option in the constructor.

Re: Media Wiki API 'WrongToken'
by bliako (Prior) on May 24, 2018 at 11:28 UTC

    Hey RandomWalk, I think your problem might be the uri-escaping of your token. Which you perform but from what i can see you do not send over. Instead your query seems to have the last slash of the token escaped (i.e. token ends in \\) but not the plus sign. Try sending the uri-escaped token over through your query.

    Check your tokens here - this sends your uri-escaped token:

    Although it says invalid (maybe action is wrong), it returns a created-date which leads me to think uri-escape (or simply replace the dreaded plus sign with %2B is the correct way.

    ps. They had to use a plus sign didn't they?

Re: Media Wiki API 'WrongToken'
by soonix (Canon) on May 24, 2018 at 18:18 UTC

    For our internal Wiki (don't know which Mediawiki version, but oldish), I use MediaWiki::API, which can work from a username/password.

    The relevant parts look like:
    ... my ($url, $user, $passwd) = qw( rob.otter T +0pSeCrEt); ... use MediaWiki::API; my $mw = MediaWiki::API->new(); $mw->{config}->{api_url} = $url; # log in to the wiki $mw->login( { lgname => $user, lgpassword => $passwd } ) || die $mw->{error}->{code} . ': ' . $mw->{error}->{details}; ... my $pagename = ...; my $ref = $mw->get_page( { title => $pagename } ); unless ( $ref->{missing} ) { my $timestamp = $ref->{timestamp}; my %p = ( action => 'edit', basetimestamp => $timestamp, # to avoid edit conflicts title => $pagename, bot => '1', nocreate => '1', text => '... this is the text ...', ); $mw->edit(\%p) || die $mw->{error}->{code} . ': ' . $mw->{error}->{details} +; }; ...
    The content of the %p hash are documented on the corresponding api.php page, e.g.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1215136]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2021-04-17 09:07 GMT
Find Nodes?
    Voting Booth?

    No recent polls found