API talk:Login

From MediaWiki.org
Jump to navigation Jump to search

Login / lg[edit]

How is the password verified by the server? How is the password sent? Plaintext / encrypted? What encryption is used?

Perhaps someone more knowledgable can fill in this table:

AJAX http: url param ?
AJAX https: url param ?
AJAX http: POST data ?
AJAX https: POST data ?
Login screen http: url param ?
Login screen https: url param ?
Login screen http: POST data ?
Login screen https: POST data ?

Thanks a lot in advance, Shinobu 04:49, 20 December 2006 (UTC)

From what I can tell, HTTPS is not supported. Also, since the authentication is form-based, the only option for sending the password is plain text. Using status code 401, HTTP itself supports Basic and Digest authentication as standard schemes, although Digest is not used all that often. In the case of Basic, it is effectively plain text; for Digest, it is an MD5 digest of the password, so it is effectively encrypted. All of this is moot because MediaWiki doesn't do this.
The problem is that if anything but plaintext is received by the server, you are limited in how the passwords can be stored in the database. For instance, if you use digest authentication based on MD5, the version of the password has to be based on the MD5 hash of the password, since it can't check against another hashing/crypting scheme without reprocessing the original password. In the case of MediaWiki, this would actually work, since it's database value is based on an MD5 hash of the plain text, but I'm not sure that there is consistent browser support for Digest authentication. The other issue is that using form-based authentication allows you to have a pretty HTML form for posting and let's you implement stuff like "Remember me", since HTTP authentication doesn't support this (regardless of whether you use Basic or Digest). Hope that helps. Mike Dillon 16:38, 22 December 2006 (UTC)
What I said about Digest authentication is a little inaccurate; since it isn't relevant to what MediaWiki does, you can just ignore my correction if you aren't interested.
The real problem is that without access to a plaintext versions of the password on the server, the server can't reproduce the expected response in the challenge/response protocol. This is because the response is based on the MD5 hash of not just the password, but other information as well. Since MediaWiki only stores the MD5 hash of the password, it can't generate the expected hash when the other components of the HA1 hash are factored in (see Digest authentication for more details).
There are further complications if MediaWiki has been configured with the $wgPasswordSalt setting, since it actually double-hashes to get the value that's stored in the database in that case. Since MD5 is a one-way hash, there is no way for the server to get back to the original password. All it can do is verify that what the user sent as the password can be re-hashed to the same value. Mike Dillon 04:42, 24 December 2006 (UTC)

So in summary, the password is always sent in plaintext?

@From what I can tell, HTTPS is not supported: I think https is supported: Main Page (https), so I should think that only URLs are passed unencrypted, right? POST data and responses should be encrypted. Unfortunately, it doesn't seem to know that I already signed in on http, so apparently when you use the https login you have to do everything in https. Question is, is API supported using https?

@form-based, the only option for sending the password is plain text: One could calculate the MD5 hash using JavaScript, or one could use https. Considering I've already sent my password in plaintext, it should at least be possible to verify and/or change it without doing so again. Sending the password in plaintext again and again seems even less wise than doing it once.

I'm pretty new at this, but sending passwords in plaintext seems pretty dumb to a layman. Not warning about it even more so. Shinobu 08:03, 24 December 2006 (UTC)

I didn't know about secure.wikimedia.org. I'm not sure that you can log in to that server and get a cookie that will work on a non HTTP version, though. I just tried to use: https://secure.wikimedia.org/wikipedia/en/w/api.php?action=login&format=xml&lgname=Username&lgpassword=Password&lgdomain=en.wikipedia.org and I got a cookie in "secure.wikimedia.org", which means that all traffic must go through that domain instead of en.wikipedia.org. Also, since the server sets the "secure" flag on the cookie, normal HTTP libraries won't send it to the plain HTTP URLs on secure.wikimedia.org, so you have to take the SSL overhead on every request to stay logged in. If you aren't trying to use the cookies returned, you should be able to use the lgtoken value returned in the API response against en.wikipedia.org, but I haven't tested that. I didn't look into what is done on the server side with the login token.
As for what is encrypted when using HTTPS, everything is encrypted, including the URL. All that can be seen by sniffing is that you're sending data to the server's IP address using SSL. You can't see any headers or the HTTP request body or URL, since they're part of the SSL payload.
Regarding the use of Javascript to send an MD5 hash, it could be done, but the MediaWiki software would have to support it and you'd have to find Javascript code to do the hashing.
I'm not sure what you mean about sending the password again and again. It should only be sent to the login action. After that, you either use the cookies returned or the login token in the API response to send what is effectively a session id, not your password. Mike Dillon 20:31, 24 December 2006 (UTC)

Regarding encryption on secure.wikimedia.org, I just saw this post on English Wikipedia's technical village pump. The poster claims that the "null" cipher is possibly being used for the HTTPS server and if so even that is not encrypted... I just checked it and saw "AES 256", so I'm not sure whether it is encrypted or not. The browser said it was AES 256 and the stream looked encrypted in a packet capture, so this is mainly just an FYI. I'm not sure if there is any documentation on the cipher used by the HTTPS server. Mike Dillon 00:23, 27 December 2006 (UTC)

There have been some additions to the aforementioned discussion from Brion VIBBER. The null encryption thing is not true, but he mentions some other quirks of the secure.wikimedia.org server. See en:Wikipedia:Village pump (technical)#Status of secure.wikimedia.org?. Mike Dillon 15:33, 27 December 2006 (UTC)

@you'd have to find Javascript code to do the hashing: There is a module to do this. w:User:Lupin/md5-2.2alpha.js Although one should be careful about what to hash, because otherwise the hash could be sniffed and used instead, defeating the purpose of sending a hash.

As much as I understand this to be a complicated issue, I still think it needs to be fixed. Shinobu 19:06, 28 December 2006 (UTC)

I just tried the following:
  1. Log in using API to secure.wikimedia.org
  2. Note the lgusername, lgtoken, and lguserid fields in the response
  3. Request a watchlist against en.wikipedia.org using those values
Unfortunately, I received <error code="wlnotloggedin" info="You must be logged-in to have a watchlist">. As I said before, I haven't looked into how the tokens work to see what the problem might be, but I would think this should work. Of course, at that point your session can be hijacked since you're sending the token over the wire unencrypted, but there's really no way to avoid this except for using SSL for every request. At least nobody can steal your password...
I also noticed that I get the same token back for subsequent login requests. Mike Dillon 22:13, 30 December 2006 (UTC)
I am also trying to the exact same thing as Mike Dillon said above. I've gone through the same steps with the same lack of result. I'm passing lgusername, lgtoken and lguserid in POST, and verifying this in my app before it goes out. I'm extremely new the API, but trying getting it rapidly except for this hiccup. Any progress here? Eddieroger 05:58, 13 February 2007 (UTC)
Hope this helps : Example of the Atom authentification (the only remaining problem is that passwords are kept in clear by the server, but the transaction is secure). I don't know if there is an updated version. w:fr:Leafcat

I hate reopening old issues, but I still can't get login working without using cookies. I am able to login with result code of "success," but when I pass those parameters back in to the API along with my request, I still get wlnotloggedin errors. I'm testing this against en.wikipedia.org as a normal non-bot user. Can anyone confirm that it works at all? Eddieroger 23:16, 4 August 2007 (UTC)

Same problem, (In PHP):
$wiki = 'http://en.wikipedia.org/';
$url = $wiki . 'w/api.php?action=login&lgname='.$username.'&lgpassword='.$password.'&format=xml';
$http = http_parse_message(http_get($url))->body; /* Works */
$xml = simplexml_load_string($http);
$login = "&lgtoken={$xml->login['lgtoken']}&lgusername={$xml->login['lgusername']}&lguserid={$xml->login['lguserid']}";
$url = $wiki . 'w/api.php?action=query&list=watchlist' . $login;
$watchlist = http_parse_message(http_get($url))->body; /* <error code="wlnotloggedin" info="You must be logged-in to have a watchlist">*/
Carpetsmoker 06:02, 27 August 2007 (UTC)

It seems I am having the same problem. When trying to issue a recentChanges query using a PHP program, I get very different results than when I log in to a browser and issue the same query from the browser window. It seems there are problems with the login and token passing in the URL query string, but seems to work fine if I use cookies. Formatting cookies in PHP is no where near as easy as formatting a query string :-( 14:30, 11 September 2007 (UTC)

Try Snoopy, a PHP class that makes this stuff easier. --Catrope 15:05, 11 September 2007 (UTC)
I believe the secure and unsecure servers require separate logins.— Preceding unsigned comment added by Smallman12q (talkcontribs)


Am I getting it right that currently login works only via GET and you have to disclose your login in URL? MaxSem 10:47, 21 November 2007 (UTC)

No. Both GET and POST work just fine for all API modules. --Catrope 13:43, 21 November 2007 (UTC)
No, certain api modules such as login require that you do a post.— Preceding unsigned comment added by Smallman12q (talkcontribs)


Hello. Since few days iv got problem to connect my robot with the API. Checking the code, i see i receive "Scripts should use an informative User-Agent string with contact information, or they may be IP-blocked without notice.". But the error is not embbeded into XML, then everything crash. Then, is there a way to embbed this message into XML?

My second problem is i dont know what "informative User-Agent string with contact information" mean. I really dont know where i can ask help. Maybe it is outside the topic of the page. I dont know. 20:56, 18 February 2010 (UTC)

See m:User-Agent_policy. Tisane 12:04, 6 May 2010 (UTC)

New problem with API:login[edit]

I'm using api.php for a while now for a set of tools around my bots (on fr.wikipedia.org). Today I get a problem to log in (but maybe it exists before, but my token was expired, so I really my program really attempt a login).
When I try to log, I get a "NeedToken" reply, with a associated token:

           [result] => NeedToken
           [token] => faab82e4158d864b9f06304c9cb870ec

I don't understand why, because this part of the code works for mounthes without any problem.
I also tried to add lgtoken=faab82e4158d864b9f06304c9cb870ec (in this example) to the POST data (with the lgname and lgpassword) with exactly the same effect: it still replies a "NeedToken" and gives a new "token" value.

Any clues to help me? If it can help this part of the code is an independant script in shell (Linux) using Curl, code that is used for at least 3 mounthes by now.

Regards, Hexasoft 09:57, 9 April 2010 (UTC)

Details: login action is performed this way:
curl -A "My user string" -s -d "lgname=Hexabot&lgpassword=mypassword" "http://fr.wikipedia.org/w/api.php?action=login&format=txt" (-d option is the POSTed data)
I also tried passing "lgname=Hexabot&lgpassword=mypassword&lgtoken=the_token_in_previous_reply" without success.
Hexasoft 10:02, 9 April 2010 (UTC)
Hi, the login procedure has changed a few days ago, and every tool need to be modified to work with it. The new procedure is described here. I did it for my own tool without any problem. --NicoV 11:21, 10 April 2010 (UTC)
Ok! Thanks. I applied this method and my login now works. Regards, Hexasoft 11:49, 10 April 2010 (UTC)

I experienced the same problem with my bot on Wikia after they updated the software. Unfortunately, when I try to get the token in the first request I only receive the token itself (<api><login result="NeedToken" token="b23e34a7e2f03b0e9ae2178ea23cdb21" /></api>) but not the cookieprefix or sessionid for the second request (which also returns a NeedToken error). I checked the HTTP headers and they don't send a cookie, either. It would be great if someone who fixed the problem for his bot could tell me how he got the sessionid from the response. Have a nice weekend, 20:43, 17 April 2010 (UTC)

Send a first login request (with lgpassword and lgname) to receive the token, then send a second login request (with lgpassword, lgname and lgtoken).
--NicoV 15:49, 18 April 2010 (UTC)
Thank you for your fast response; I fixed my mistake. In case anyone else has the same problem, my script is written in JavaScript and AJAX and I was using a PHP proxy to relay the request to the wiki server. The wiki server returned the correct response including the HTTP cookies back to the proxy but my proxy only returned the XML part of the response, not the session cookies. Therefore, on my computer I did not see any cookies when I was looking at the HTTP headers. I had to change the proxy script so that the cookie would be returned as well. Thank you again for your quick answer. -- 19:17, 18 April 2010 (UTC)

I am doing the same thing. I make a second call with the lgtoken value set. How do you pass the cookie in PHP? What I did was have the CURLOPT_HEADER be TRUE, so that I would get the header back. Then I parsed the header for the session id, then did this in the second API call:

curl_setopt ($curl_obj2, CURLOPT_COOKIE, 'wiki_session='.$sessionId);

But it's very unpredictable. It works sometimes, doesn't at others. Is there some way to do this without using Snoopy. I'm working in a corporate environment and use of open source isn't encouraged, unless it's really well established. It's a big thing that I'm using MediaWiki at all. --Jogjayr 23:13, 8 June 2010 (UTC)

Throttling setting[edit]

How does one change the throttling setting to something other than 5 logins per 300 seconds? Thanks, Tisane 13:20, 6 May 2010 (UTC)

Take a look here: Manual:$wgPasswordAttemptThrottle JRWR / wiki@jrwr.co.cc

is there a possibility to...[edit]

...check if someone is online (login) or not? And is it possible to add this in a wiki with mediawiki 1.15.1? -- 12:18, 11 August 2010 (UTC)

Extension:WhosOnline. Max Semenik 12:51, 11 August 2010 (UTC)
Yeah... I know this function, but WhosOnline works with edits. I think of something that works with the button Log in/out... -- 13:13, 11 August 2010 (UTC)

Automate Browser Login[edit]

Is it possible to use this API to login on behalf of the browser?

I have successfully performed a login and login confirmation, but that just allows my server to communicate with the Wiki via the API calls.

What I really wanted to do was to log in on behalf of the user (my web site was going to store their mediawiki username and password, with their permission), then allow him or her to continue browsing. However, as my script can't set the username, userid, session and token cookies for a different domain, I'm beginning to think this can't be done.

Any suggestions?

Thanks — Preceding unsigned comment added by (talkcontribs) 08:02, 15 October 2010‎

I don't think you can do that very easily. (You could probably do something with forcing your users at site A to load an image from your mediawiki site that sets the cookie based on information received from the server of site A, like how central auth does multi-wiki logins, but that'd probably require you to write an auth extension). Bawolff 22:12, 19 October 2010 (UTC)

logging in with FauxRequest[edit]

Hello, here is a newbie question: I'm trying to upload an image to my own Mediawiki installation from an extension, and I need to log in to do that via the API. However:

	$request = new FauxRequest( array(
		'action' => 'login',
		'lgname=' => 'mylogin',
		'lgpassword' => 'mypassword',
	$api = new ApiMain( $request); 

...returns as result only 'NoName', supposedly to mean that lgname is not defined. What am I missing?

rotsee 13:11, 17 April 2011 (UTC)

'lgname=' => 'mylogin',

is misspelled.


'lgname' => 'mylogin',

— Preceding unsigned comment added by (talkcontribs) 22:38, 12 November 2014

How to Login from desktop window application?[edit]

There is a website built with MW 1.18.2, which requires users to log in - without this you cannot access any page in it. I have valid credentials to log in manually from browser, but I need to be able to do the same from my windows forms application (C#): when user clicks on a button I have to show (or navigate to) certain page from the website, and for that I have to login programmatically first. I see the examples in PHP and JScript but being newbie in that web staff I have no idea how to use them.

Any help would be greatly appreciated.

Thanks. — Preceding unsigned comment added by 2013‎ (talkcontribs) 12:40, 18 October

Problem using login API on Waze wiki[edit]


My application, WPCleaner works fine on Wikimedia wikis (Wikipedia, Wiktionary, ...), but my attempts to make it work on Waze wiki have failed for now. I don't understand why login doesn't work on Waze wiki. Would someone have an idea about this problem ?

The first call to the login method for waze wiki returns a "NeedToken" answer as usual, with a session id in the answer and a wikidb_session cookie. When I call the login method a second time, with wikidb_session cookie set and the token, the answer from waze wiki is again a "NeedToken" with a different session id and wiki_session cookie.

Apart from this, the only difference that I noticed is the cookie name: enwikiSession for enwiki, wikidb_session for waze (no uppercase letter and an underscore).

Here's what my logs are saying when calling enwiki login:

POST https://en.wikipedia.org/w/api.php?action=login&lgname=NicoVTest&format=xml
Request header:Accept-Encoding: gzip
Request header:User-Agent: WPCleaner (+http://en.wikipedia.org/wiki/User:NicoV/Wikipedia_Cleaner/Documentation)
Request header:Host: en.wikipedia.org
Request header:Content-Length: 60
Request header:Content-Type: application/x-www-form-urlencoded

Response header:Server: nginx/1.1.19
Response header:Date: Fri, 11 Jul 2014 21:58:05 GMT
Response header:Content-Type: text/xml; charset=utf-8
Response header:Content-Length: 159
Response header:Connection: keep-alive
Response header:X-Content-Type-Options: nosniff
Response header:Cache-control: private
Response header:Set-Cookie: enwikiSession=XXXXXX; path=/; secure; HttpOnly
Response header:X-Frame-Options: SAMEORIGIN
Response header:Content-Encoding: gzip
Response header:Vary: Accept-Encoding
Response header:X-Varnish: 2249630267, 3978847279, 3259701709
Response header:Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Response header:Accept-Ranges: bytes
Response header:Age: 0
Response header:X-Cache: cp1068 miss (0), amssq53 miss (0), amssq43 frontend miss (0)
Response header:Set-Cookie: GeoIP=XXXXXX; Path=/; Domain=.wikipedia.org

POST https://en.wikipedia.org/w/api.php?action=login&lgname=NicoVTest&format=xml
Request header:Accept-Encoding: gzip
Request header:User-Agent: WPCleaner (+http://en.wikipedia.org/wiki/User:NicoV/Wikipedia_Cleaner/Documentation)
Request header:Host: en.wikipedia.org
Request header:Cookie: $Version=0; enwikiSession=XXXXXX; $Path=/
Request header:Cookie: $Version=0; GeoIP=FR:Clamart:48.8000:2.2667:v4; $Path=/; $Domain=.wikipedia.org
Request header:Cookie2: $Version="1"
Request header:Content-Length: 101
Request header:Content-Type: application/x-www-form-urlencoded

Responses headers...

And the logs when calling waze wiki login:

POST https://wiki.waze.com/wiki/api.php?lgpassword=XXXXX&action=login&lgname=NicoVTest&format=xml
Request header:Accept-Encoding: gzip
Request header:User-Agent: WPCleaner (+http://en.wikipedia.org/wiki/User:NicoV/Wikipedia_Cleaner/Documentation)
Request header:Host: wiki.waze.com
Request header:Content-Length: 62
Request header:Content-Type: application/x-www-form-urlencoded

Response header:Cache-Control: private
Response header:Cache-control: no-cache="set-cookie"
Response header:Content-Encoding: gzip
Response header:Content-Type: text/xml; charset=utf-8
Response header:Date: Fri, 11 Jul 2014 22:00:55 GMT
Response header:Server: nginx/1.1.19
Response header:Set-Cookie: wikidb_session=XXXXXX; path=/; secure; HttpOnly
Response header:Set-Cookie: AWSELB=191167A308A57C43B5D163A49A25B6EA216AC961ACDACCD786A7F86CF60CB7DDA816851FC0DC6FA0FA203C21DE3B646E62AAF326EE53AE742952C05529425567AFC89D9424;PATH=/
Response header:Vary: Accept-Encoding
Response header:X-Content-Type-Options: nosniff
Response header:X-Frame-Options: DENY
Response header:Content-Length: 166
Response header:Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>
  <login result="NeedToken" token="XXXXXX" cookieprefix="wikidb" sessionid="XXXXXX" />

POST https://wiki.waze.com/wiki/api.php?lgtoken=XXXXX&lgpassword=XXXXX&action=login&lgname=NicoVTest&format=xml
Request header:Accept-Encoding: gzip
Request header:User-Agent: WPCleaner (+http://en.wikipedia.org/wiki/User:NicoV/Wikipedia_Cleaner/Documentation)
Request header:Host: wiki.waze.com
Request header:Cookie: $Version=0; wikidb_session=XXXXXX; $Path=/
Request header:Cookie: $Version=0; AWSELB=191167A308A57C43B5D163A49A25B6EA216AC961ACDACCD786A7F86CF60CB7DDA816851FC0DC6FA0FA203C21DE3B646E62AAF326EE53AE742952C05529425567AFC89D9424; $Path=/
Request header:Cookie2: $Version="1"
Request header:Content-Length: 103
Request header:Content-Type: application/x-www-form-urlencoded

Response header:Cache-Control: private
Response header:Content-Encoding: gzip
Response header:Content-Type: text/xml; charset=utf-8
Response header:Date: Sat, 12 Jul 2014 08:00:40 GMT
Response header:Server: nginx/1.1.19
Response header:Set-Cookie: wikidb_session=XXXXXX; path=/; secure; HttpOnly            DIFFERENT THAN THE ONE IN THE FIRST CALL
Response header:Vary: Accept-Encoding
Response header:X-Content-Type-Options: nosniff
Response header:X-Frame-Options: DENY
Response header:Content-Length: 165
Response header:Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>
  <login result="NeedToken" token="XXXXXX" cookieprefix="wikidb" sessionid="XXXXXX" />

Token and session id returned in the second call are different than the one returned in the first call.

Any idea on what's going on? --NicoV (talk) 22:14, 11 July 2014 (UTC)

Problem found: apparently Waze server has a problem with multiple Cookie headers... I forced the use of a single Cookie header and it seems to work now. --NicoV (talk) 15:44, 14 July 2014 (UTC)


My limited understanding of Extension:OAuth is that using action=login is not required after oauth. Are their other ways to login without action=login? The first sentence and others could be slightly improved to indicate that there are other ways to login to the API without this action. John Vandenberg (talk) 10:15, 5 June 2015 (UTC)

Using centralauthtoken (from Extension:CentralAuth) also avoids needing to use action=login. There might be other extensions that do the same sort of thing.
In all these cases it's more or less the same as when you have the cookies set after logging in normally: you have an authenticated session already so you don't need to use action=login to get one. Anomie (talk) 13:44, 5 June 2015 (UTC)
Thanks for a bit of background. I've taken a crack at rewriting the intro. Would appreciate timely copyedits before it is sent off to translators, or a revert if necessary.
I see JavaScript clients are mentioned in the section below the intro, so that might be a good spot to mention OAuth, temporarily at least. John Vandenberg (talk) 01:07, 6 June 2015 (UTC)
Looks good to me. Anomie (talk) 13:22, 8 June 2015 (UTC)


Is "action=login" deprecated or getting deprecated? API in en-wiki says that we should use "action=query&meta=tokens&type=login" now. --Infovarius (talk) 21:04, 18 March 2016 (UTC)

action=login is not deprecated, but getting the login token via action=login is. You should get the login token via action=query&meta=tokens and then use that to login via action=login. --Cgt (talk) 21:07, 18 March 2016 (UTC)
Thanks for the answer. Now I am trying to do so. I'm getting "success" when logining through API sandbox, but I'm getting "WrongToken" constantly when doing the same requests in my program (URLFetch in Wolfram Mathematica). Also when I feed logintoken from sandbox. Before the change to "meta=tokens" it was possible to login. What can be the reason? Infovarius (talk) 21:43, 18 March 2016 (UTC)
Be sure you're saving the cookies returned from your request to action=query&meta=tokens, and then send them on your request of action=login --Ciencia Al Poder (talk) 11:50, 20 March 2016 (UTC)
Thanks, but not working. I am saving the cookies and send them on request of action=login. Something strange that first request doesn't require user login... Why after API changes developers don't update documentation here? --Infovarius (talk) 21:49, 20 March 2016 (UTC)
Would love to learn how to pass cookies from the first login to the second (using Google Apps Script here). HausaDictionary (talk) 06:33, 5 August 2017 (UTC)

Localized error messages[edit]

Hello! I tried to tack on a uselang=es parameter to the clientlogin sample[0] but the error messages are still in English:

"error": {
  "code": "loginmustpostparams",
  "info": "The following parameters were found in the query string, but must be in the POST body: logintoken",
  "*": "See https://www.mediawiki.org/w/api.php for API usage"

I know this particular error is due to developer misuse but generally speaking, is there a means to localize these responses so clients can present a human readable message to their users? Thanks!

[0] https://www.mediawiki.org/w/api.php?action=clientlogin&uselang=es&username=Example&password=ExamplePassword&loginreturnurl=http://example.org/&logintoken=123ABC

— Preceding unsigned comment added by Niedzielski (talkcontribs)

Sadly, it seems like it's a hardcoded message: [1]. There has been an effort to localize the help system of the api and some error messages. You can request messages like this to be localizable.
Also note that errors from api contains a code (loginmustpostparams in this case) that you can use to replace the error message with a custom one when presenting the error to the user. That, of course, requires you to know beforehand all possible error codes that particular api module can throw... --Ciencia Al Poder (talk) 09:49, 5 October 2016 (UTC)
FYI, the relevant task is phab:T47843. And it's on my short list of things to do next time I have time for major API work. Anomie (talk) 13:42, 5 October 2016 (UTC)
Thank you both! Niedzielski (talk) 20:22, 5 October 2016 (UTC)

Support of both kinds of credentials?[edit]

Obviously, API:Login supports two kinds of credentials (beside OAuth):

  1. main-accounts → action=clientlogin is required
  2. bot-accounts → action=login is required

Up to now, I'm not able to detect a way, how both kinds of credentials could be used by a client. It looks like usage of one kind of credential excludes the usage of the other one. Did I miss something?

To illustrate my concerns:  I'm working at development of LrMediaWiki, a plug-in for Adobe Photoshop Lightroom which enables Lightroom users to upload images to a MediaWiki instance. Users need to login to upload images. Due to usability reasons, user's credentials are stored by the plug-in and the latest stored credentials are used by following logins/uploads – this means: users shouldn't be annoyed by typing credentials at every usage of the plug-in. I mention this, because I don't know, if this plug-in should be considered to be an "interactive" client or not.

Recently I detected deprecated API calls related to the login at the plug-in's log file:

  • Fetching a token via action=login is deprecated. Use action=query&meta=tokens&type=login instead.
  • action=tokens has been deprecated. Please use action=query&meta=tokens instead.
  • Main-account login via action=login is deprecated and may stop working without warning. To continue login with action=login, see Special:BotPasswords. To safely continue using main-account login, see action=clientlogin.

According to these messages and the methods recommended at API:Login, I consider to use action=clientlogin for future versions of LrMediaWiki to resolve the deprecated issues. I'm not sure, if this decision was right. Maybe, action=login might fit better to LrMediaWiki, but it seems this would support only bot-accounts, not main-accounts.

LrMediaWiki needs to support both kinds of credentials, main-accounts and bot-accounts. Up to now, LrMediaWiki works in a "traditional" way of login and supports both kinds of credentials, but yields to the mentioned deprecated messages. My tries to resolve the deprecated issues (first determine a login token, then using action=clientlogin) works successful with main-accounts, but bot-accounts don't work.

  • Testing bot-accounts with a non-WMF MediaWiki 1.28.0 instance yields an error message "The supplied credentials could not be authenticated." (If $wgLanguageCode is set to "de": "Die angegebenen Anmeldeinformationen konnten nicht überprüft werden.")
  • Testing bot-accounts with commons.wikimedia.beta.wmflabs.org running MediaWiki 1.29.0-alpha results to an error message "Incorrect password entered. Please try again."

Therefore I assume, action=clientlogin doesn't support bot-accounts.
Any idea, how the LrMediaWiki client could/should support both kinds of credentials? --Hasenläufer (talk) 05:11, 3 January 2017 (UTC)

action=clientlogin was written because there's no way to make action=login reliably work with AuthManager. Main account login must use AuthManager. Note that main account login need not depend on a username and password, it could as easily be a redirect to Google's authentication service if appropriate extensions are installed. It might also require a captcha, or require input of a second-factor TOTP token, or require some other user interaction.
Bot passwords were created specifically to bypass AuthManager so existing bots could continue working using action=login instead of being forced to be rewritten to use OAuth. There's no sane way to make them work inside AuthManager, so action=clientlogin isn't going to accept them.
If you want to support both types in your framework, the application will need to decide which it's going to use and choose the appropriate methods. It's unlikely to be useful to present the end user with the choice: either you're interactive so you should use action=clientlogin, or you're noninteractive and should use OAuth or action=login with credentials saved in your configuration. Anomie (talk) 15:37, 3 January 2017 (UTC)
Thanks a lot! --Hasenläufer (talk) 17:48, 3 January 2017 (UTC)
What about wikis that choose not to use OAuth? Does that affect the choice of login method at all? Robin Hood  (talk) 18:39, 3 January 2017 (UTC)
OAuth should not be a prerequisite. Now I proof the username before login. If there is a @-character in it, it's a bot-account and login is done with action=login. If not, it's a main-account and login is done with action=clientlogin. The @-character must not be part of a main-account's username. --Hasenläufer (talk) 20:29, 4 January 2017 (UTC)

Login with Bot(Password) not possible[edit]

Hi! Today I fiddled around with my MW-API (v1.27.2) and a registered bot-user (Special:BotPassword) using the Httpful PHP client library. Making GET queries is working very well. But I can’t login, I want to edit and create pages, and wanna some help, please.

Like I understood I have to make 2 requests: 1. = GET to "api.php?action=query&meta=tokens&type=login" 2. = POST to "api.php?action=login". I made a small code sample that you can find here.

With the 1st request I save the login-token and the cookie (from the header). Making the 2nd request I have to send "lgname", "lgpassword" and "lgtoken" in the body and the cookie in the header. − But then I get the API warning: "Fetching a token via action=login is deprecated. Use action=query&meta=tokens&type=login instead." => What’s wrong here!? (If I use the body-parameters as URL-parameters I get the API warning: "The following parameters were found in the query string, but must be in the POST body: lgpassword, lgtoken".)

Thanks a lot for a solution and best regards! — Preceding unsigned comment added by (talkcontribs) 16:05, 12 April 2017 (UTC)

The syntax of the Set-Cookie header is not appropriate to be dumped into the Cookie header for a subsequent request, and in particular it will break if you ignore the warning in the fourth paragraph of RFC 6265 § 3 as that Httpful library appears to. Ideally you should use a library that correctly handles cookies correctly for you. Anomie (talk) 13:35, 13 April 2017 (UTC)


I am trying to login using action=clientlogin via javascript Ajax call and backend as well but for some reason I am always getting same error { "code": "badtoken", "info": "Invalid CSRF token.",....} If I use same parameters and call from POSTman it works and I get logged in. What could be wrong or am I missing something thats not required by call from POSTman, Thanks — Preceding unsigned comment added by Mujji89 (talkcontribs) 16:47, 23 April 2017 (UTC)

Looks like you did not send the session cookies (did not set withCredentials). --Tgr (WMF) (talk) 16:47, 23 April 2017 (UTC)
how to send the session cookies? Like Mujji89, I am trying to login using action=clientlogin via php+curl,but always get error
     "error": {
       "code": "badtoken",
       "info": "Invalid token",
       "*": "See http://localhost/api.php for API usage"
And I use same parameters send post in Postman it works. I know that means I didn't handling cookies properly, but CURLOPT_COOKIEJAR didn't work, I didn't know how to set-cookie manually. I've been stuck for so long. I really appreciate some help here. Thanks. here is my code: login by login API login by clientlogin API I think both of them make same mistakes. --Lsherwinforone 10:32,18 May 2017(UTC)

Can't login with bot account[edit]

Hi, I'm setting up a bot account for another wiki and I came across this problem. How do I log in with the API correctly? Currently I have:

#btw this is in Python
import lxml.html as lx, lxml.etree as tr, requests as request
SESSION = request.session()
token = lx.fromstring(SESSION.get(WIKI_API,params={'action':'query','meta':'tokens','type':'login','format':'xml'}).text).cssselect('tokens')[0].attrib['logintoken'] #get login token
req = SESSION.post(WIKI_API,data={'action':'login','lgname':myuser,'lgpassword':botpass,'lgtoken':token,'format':'xml','bot':'true'}) #where myuser is the main acc name of the bot acc and botpass is the main acc password.

The error I get when I do this is "Aborted", reason: "Authentication requires user interaction, which is not supported by action=login. To be able to login with action=login, see Special:BotPasswords. To continue using main-account login, see action=clientlogin." I looked at Special:BotPasswords and created a bot password, but if I substitute "Operator@BotName" for "myuser" and the bot password I created for "botpass" then it throws "Failed", reason: "The supplied credentials could not be authenticated." Some help?-- 07:51, 19 June 2017 (UTC)

NeedToken response but passing token from token query[edit]

I have in the past used the python requests library to login to our mediawiki installation but am running into trouble. The approach I'm following comes straight from this page here: [2] but suddenly stopped working.

# get login token
r1 = session.get(apiUrl, params={
	'format': 'json',
	'action': 'query',
	'meta': 'tokens',
	'type': 'login'

# log in
r2 = session.post(apiUrl, data={
	'format': 'json',
	'action': 'login',
	'lgname': userName,
	'lgpassword': passWord,
	'lgtoken': r1.json()['query']['tokens']['logintoken'],

r2.json returns:

{'login': {'result': 'NeedToken', 'token': '065e5e65f15a822ef1ace9df091ff8035ace2d79+\\'}, 'warnings': {'main': {'*': 'Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes.'}, 'login': {'*': 'Fetching a token via "action=login" is deprecated. Use "action=query&meta=tokens&type=login" instead.'}}}

Now NeedToken is explained as: "if the lgtoken parameter was not provided or no session was active (e.g. your cookie handling is broken)."

Could this be due to a server side change that was made? --Wuestenarchitekten (talk) 16:16, 11 April 2018 (UTC)

Login Without User-Interaction?[edit]

Reading this doc, it sounds like code can login to the API as a bot, using login, without any user-interaction.

Correct? Johnywhy (talk) 19:15, 2 July 2018 (UTC)

If it's using bot passwords, yes. Login using the main account password using action=login is deprecated in favor of action=clientlogin, which specifically does have the possibility of requiring user interaction, and trying to use action=login in this manner may fail if user interaction is required (e.g. for two-factor authentication). On Wikimedia wikis and others using Extension:OAuth, that is a better option for making logged-in requests. Anomie (talk) 13:28, 3 July 2018 (UTC)

How to check if bot is logged-in?[edit]

This section says i can check login-status with API:Userinfo, but UserInfo seems to apply to the current user, NOT to bots.

"Returns information about the currently logged-in user"

How to check if a bot is logged in? - Johnywhy (talk) 00:13, 3 July 2018 (UTC)

You seem to be confused. The bot can check if it itself is logged in by using userinfo.

There is no way for one user (e.g. you) to check if another user (e.g. your bot) is "logged in". And that question doesn't even make a whole lot of sense with the way logged-in sessions work. For example a logged-in session might still exist for some user despite no device being able to use that session due to deleted cookies. For another example, a logged-in session might not currently exist for a user, but they might still be "logged in" thanks to the remember-me cookies or OAuth credentials that will trigger a fresh session creation the next time they access the site. Anomie (talk) 13:33, 3 July 2018 (UTC)

So, i think you mean, when they say "the currently logged-in user", they mean "the bot", IF UserInfo is run in the same session as the bot. Correct?
The 2 other scenarios you mentioned (eg user deleted the cookies) concern a human-user more than a bot-session, correct?
- Johnywhy (talk) 05:21, 4 July 2018 (UTC)
In answer to your first question, yes. The currently logged-in user is specific to the session, so assuming the bot has its own cookie storage mechanism that's not shared with anything else, and that it's logging into a dedicated account rather than the bot-owner's account, then there are only two possibilities in traditional login scenarios: userinfo will report that the current user is the bot, or it will report that the current user is anonymous (user ID is zero). In the latter case, the bot needs to log in. Similarly, as long as you're sure that the bot is the only thing ever using those cookies, assertuser is sufficient to tell that the bot is logged in. If your bot is using session cookies only, and not saving them anywhere, then you're down to one possibility: the bot always needs to log in.
So, a typical userinfo check would use, for example, https://en.wikipedia.org/w/api.php?action=query&meta=userinfo and then check one of:
  • If the bot has dedicated cookie storage: id != 0 means it's logged in; anything else means it's not.
  • If the bot shares cookies with something/someone else: name == "<BotName>" means the bot is logged in; anything else means it's not.
Is that clearer now? Robin Hood  (talk) 07:37, 7 July 2018 (UTC)

New example responses[edit]

@SSethi (WMF): In your recent edits, you added example response output that looks like


My guess is that that is actually some Python version of PHP's var_dump, rather than the API's actual output? The actual API output in JSON format (and pretty-printed) would look like this:

   "login": {  
      "lguserid": 21,
      "result": "Success",
      "lgusername": "William"

Note how the <syntaxhighlight lang="json"> applies syntax highlighting when the format is actually JSON. Anomie (talk) 13:19, 14 September 2018 (UTC)

Oops! Thanks for the catch. I've modified the response output. SSethi (WMF) (talk) 19:57, 17 September 2018 (UTC)

Action=login deprecated even with bots[edit]

Hello, I want to use a bot in my wiki via API and I could not log it in. I'm using BotPasswords and action=login but when I do the request return this:

    "warnings": {
        "main": {
            "*": "Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
        "login": {
            "*": "Fetching a token via \"action=login\" is deprecated. Use \"action=query&meta=tokens&type=login\" instead."
    "login": {
        "result": "NeedToken",
        "token": "5102e85b553e4eb7589cbb88608ca4805c8ba77b+\\"

If I test in sandbox, returns success.

   "login": {
       "result": "Success",
       "lguserid": 1,
       "lgusername": "Byz001"

I'm using MW 1.31. Does anyone have the same issue? Thanks. — Preceding unsigned comment added by Crismagnabosco (talkcontribs) 13:54, 15 March 2019 (UTC)

As the message says, you should be using the method described in API:Tokens to fetch the login token rather than relying on the "NeedToken" response from action=login. In Special:ApiSandbox you're probably using the feature that fetches the login token for you. Anomie (talk) 13:11, 18 March 2019 (UTC)

Hi. I did the requests as described in doc. First, I fetch the login token and then a request the login and the erros continues. This is the code:
using (WebClient webClient = new WebClient())
    webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
    // fetch the logintoken
    var parameters = new NameValueCollection();
    parameters.Add("action", "query");
    parameters.Add("format", "json");
    parameters.Add("meta", "tokens");
    parameters.Add("type", "login");
    byte[] responsebytes = webClient.UploadValues("http://mywiki/api.php", "POST", parameters);
    string resultRequest = Encoding.UTF8.GetString(responsebytes);
    // extract logintoken from result
    string token = GetLoginToken(resultRequest);
    webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
    // try to login
    var parameters = new NameValueCollection();
    parameters.Add("action", "login");
    parameters.Add("format", "json");
    parameters.Add("lgname", "myuser");
    parameters.Add("lgpassword", "mypass");
    parameters.Add("lgtoken", token);
    responsebytes = webClient.UploadValues("http://mywiki/api.php", "POST", parameters);
    resultRequest = Encoding.UTF8.GetString(responsebytes);
Thanks — Preceding unsigned comment added by Crismagnabosco (talkcontribs) 16:23, 18 March 2019 (UTC)
Check that your "webClient" object is properly handling cookies, and that it's submitting the correct value for the lgtoken parameter. Other than that, you'll have to figure things out on your own. Anomie (talk) 13:07, 19 March 2019 (UTC)

Mediawiki authentication[edit]


I'm working on an IONIC application connected to a plateform built using Mediawiki, and i want to add a login page in my mobile application to get connected to the plateforme.

I tried first something like this https://www.mediawiki.org/wiki/API:Login#Sample_code_2 in Posteman and all i get is:

``` {"batchcomplete":"","query":{"tokens":{"logintoken":"3d685e00f7fff70211e05040431c8ec55cb6f333+\\"}}} ``` regardless which requets i send ( Post or Get ).

My question is, is there any way to get loged to Mediawiki using a login and password ( testable on Postman )

Thanks — Preceding unsigned comment added by Adnane.lamghari (talkcontribs)

Be sure you get the cookies received on the first request, and send them on the second request with the logintoken parameter. --Ciencia Al Poder (talk) 09:18, 18 April 2019 (UTC)
I cannot get this to work on 1.33.
I request the login token:
GET /api.php?action=query&meta=tokens&type=login&format=json HTTP/1.1
I get the cookie and token in the response.
Set-Cookie: low_db_low__session=muf3itiij5qdsfgj87ojidb8t19rf87l; path=/; secure; HttpOnly
            "logintoken": "7a716bd2de67cb8714a3c7315b4e66535de40203+\\"
I pass the cookie, lgtoken, lgpassword, and lgname in a POST to the login action:
POST /api.php?action=login&format=json HTTP/1.1
Cookie: low_db_low__session=muf3itiij5qdsfgj87ojidb8t19rf87l; path=/; secure; HttpOnly
    "lgname": "Username",
    "lgpassword": "password",
    "lgtoken": "7a716bd2de67cb8714a3c7315b4e66535de40203+\\"
And I still get NeedToken:
    "login": {
        "result": "NeedToken",
        "token": "2ecce64ec4054897739f6ac7c0b7e5ec5de4022f+\\"
I've tried using the NeedToken response token, URL encoding the token, omitting the +\\, nothing works.
Full workflow and HTTP responses are in this paste. -Oznogon (talk) 18:19, 1 December 2019 (UTC)
You're setting the cookie wrong. The value of the cookie is muf3itiij5qdsfgj87ojidb8t19rf87l, without the semicolon nor everything past it (path, secure, etc): those are properties sent by the server but should never be sent by the client. --Ciencia Al Poder (talk) 10:31, 2 December 2019 (UTC)

"error":{"code":"badtoken","info":"Invalid CSRF token."}[edit]

I'm trying to do a clientlogin but it seems I'm using the wrong token. I try to get my token using action:query, type:login. Before I tried to get it without adding the parameter type:login. There I always got "+\" as token. With that token login didn't work neither. --jobu0101 (talk) 08:13, 8 April 2020 (UTC)

Do you send the cookies you received first when getting the token? --Ciencia Al Poder (talk) 19:59, 8 April 2020 (UTC)
@Ciencia Al Poder: Yes, I do so. --jobu0101 (talk) 07:31, 9 April 2020 (UTC)
The cookies I receive are values for GeoIP, WMF-Last-Access-Global and WMF-Last-Access. --jobu0101 (talk) 07:41, 9 April 2020 (UTC)
When I run /w/api.php?action=query&format=json&meta=tokens&type=login I get a mediawikiwikiSession cookie. That's the important one. Of course, I only get it when my browser doesn't have it already. Can you check again the presence of that cookie? --Ciencia Al Poder (talk) 15:36, 9 April 2020 (UTC)
@Ciencia Al Poder: Strangely I now receive the (in my case) dewikiSession cookie. When I then do my second query with action=clientlogin I get a different error message now (I'm a little bit confused that it changed even though I didn't chage my code (I believe)):
{"error":{"code":"missingparam","info":"At least one of the parameters \"logincontinue\" and \"loginreturnurl\" is required.","*":"See https://de.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."},"servedby":"mw1377"}
Why would I want to add parameters logincontinue or loginreturnurl and with which value? --jobu0101 (talk) 07:32, 10 April 2020 (UTC)
My guess is that you were most likely running into T249680: Clients failing API login due to dependence on "Set-Cookie" header name casing.

The purpose of loginreturnurl and logincontinue and their expected values are explained in the documentation. They exist to support multi-step login flows that may involve redirection to a third party. Anomie (talk) 13:11, 10 April 2020 (UTC)

Thank you. My old version of my login script works now again. Maybe it was this issue with Set-Cookies and set-cookies. --jobu0101 (talk) 07:12, 11 April 2020 (UTC)