API talk:Login

Login / lg
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: 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  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). 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:
 * Log in using API to secure.wikimedia.org
 * Note the lgusername, lgtoken, and lguserid fields in the response
 * Request a watchlist against en.wikipedia.org using those values
 * Unfortunately, I received . 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; /* */
 * 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 :-( 128.221.197.20 14:30, 11 September 2007 (UTC)
 * Try Snoopy, a PHP class that makes this stuff easier. --Catrope 15:05, 11 September 2007 (UTC)

POST?
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)

User Registration
Hi all, Anybody know how to Create new users with api. I tried User registration with my own form with index.php but i'm not able to do that, The Code I user is.

 array('method' => 'POST', 'content' => $data ));			if($optional_headers != null) {				$params['http']['header'] = $optional_headers; }			$ctx = stream_context_create($params); $fp = @fopen($url, 'rb', false, $ctx); if (!$fp) {				throw new Exception("Problem with $url, $php_errormsg"); }			$response=''; while (!feof($fp)) {				$response = $response.fgets($fp); }			if ($response === false) {				throw new Exception("Problem reading data from $url, $php_errormsg"); }			fclose($fp); return $response; }		$host = 'http://127.0.0.1'; $url = $host.'/index.php'; echo $username = $_POST['wpName']; echo $password = $_POST['wpPassword']; echo $realname = $_POST['wpRealName']; $data = array ('title' => 'Special:UserLogin', 'action' => 'submitlogin', 'type' => 'signup', 'wpName' => $username, 'wpPassword' => $password, 'wpRealName' => $realname); $data = http_build_query($data); $reply = do_post_request($url, $data); var_dump($reply); exit; } else { ?> "> Create account Username: Password: Retype password: Real name:  

Anyone can tell me where i do wrong? Thanks