Ok, this is how to authenticate a Django user from PHP, or how to "read" a Django password from PHP.
I think OpenID is the best solution but I had to authenticate Django users in a PHP app sharing the same database today and this is how I solved:
<?php
/* Generates crypted hash the same way as Django does */
function get_hexdigest($algorithm, $salt, $raw_password) {
if (!array_in($algorithm, array('md5', 'sha1'))) {
return false;
}
return $algorithm($salt.$raw_password);
}
/* Checks if password matches the same way Django does */
function check_password($raw_password, $django_password) {
list($algorithm, $salt, $hsh) = explode('$', $django_password);
return get_hexdigest($algoritm, $salt, $raw_password) === $hsh;
}
?>
The key is to understand the format in which Django saves the passwords, which is:
[algorithm]$[salt]$[hash]
So for example I had an "admin" user with password "admin" and the password field in the auth_user row was:
sha1$63a11$85a93f217a72212b23fb0d5b95f3856db9575c1a
The algorithm is "sha1", the salt, which was generated randomly is "63a11" and the crypted hash is "85a93f217a72212b23fb0d5b95f3856db9575c1a".
So who do you produce the crypted hash in PHP? You simple concatenate the salt and the raw password and hash it with the algorithm, in this case, sha1:
<?php
$salt = '63a11';
$pass = 'admin';
echo sha1($salt.$admin); // prints "85a93f217a72212b23fb0d5b95f3856db9575c1a"
?>
That wasn't difficult! I got it by reading the relevant code in the Django sources.