Drupal - How do I programmatically log in a user?
This might help someone:
function mymodule_user_login_credentials($username, $password)
{
if(user_authenticate($username, $password))
{
$user_obj = user_load_by_name($username);
$form_state = array();
$form_state['uid'] = $user_obj->uid;
user_login_submit(array(), $form_state);
return true;
}
else
{
return false;
}
}
A better version based on the comment:
function mymodule_user_login_credentials($username, $password)
{
if($uid = user_authenticate($username, $password))
{
user_login_submit(array(), array('uid' => $uid));
return true;
}
else
{
return false;
}
}
There is not a simple API function for that.
You can do what Drupal does:
- Test the password by querying the database see:
user_login_name_validate()
user_login_authenticate_validate()
user_login_final_validate()
Overwrite the
global $user
.global $user; $user = user_load($uid);
Handle sessions
user_login_finalize($form_state);
For step two and 3 see user_login_submit()
All these functions are based on being called from a form. The normal flow is that the validate handlers test the users input and returns the uid of the user if validation passes. The submit handler then handles the actual login of the user and calling user hook.
If you need to get the user object for the user account for which you know username and password, then you can use the following code:
function mymodule_get_user(name, $password) {
$account = FALSE;
if ($uid = user_authenticate($name, $password)) {
$account = user_load($uid);
}
return $account;
}
$account
will be FALSE
if the user object cannot be found or loaded.
You should use this code when, for example, your module gets the username and password as input from a user, it verifies if they are correct, and then it does something with the user object.
If you are writing a module that needs to impersonate a user to write a comment, or doing something else that needs to result as done by a user, which is what the Project issue tracking module does when closing an issue report that has been in the fixed status for two weeks (in that case, it adds the comment "Automatically closed -- issue fixed for 2 weeks with no activity" which results written by the "System Message" user), then you don't need username and password. You just load the user object for which you know the user ID.
As far as I know, there aren't any security issues with the code I reported.
You could want to limit the number of failed logins; or to temporary block the IP which tries to log in without success, or tries different logins in short time.