Saturday, May 21, 2011

Drupal force login/logout

Hi,

This is not a very regular scenario, but I had got one, where I had to make a user auto login when they are coming to my website via a newsletter, that I had sent to the website members. The flow is, first I create various email newsletters and distribute it among my website users by mailing them. The newsletters would contain a link back to my website. Now when the users click that link, they come back to my website. They have to enter few basic details such as the password, gender, date of birth etc. When they click next they get logged in to the website.

I am using Drupal 6.20 for this development. The users that I am talking about are basically drupal users as well, so I need to login them in Drupal framework as well. It is actually simpler than I had thought. In Drupal whenever a user logs in it creates a global variable, "$user", instead of session variables to store the details of the logged in users. So all I had to do is to overwrite that variable with the user details who needs to be logged in.

This is the code that I had used:

$user_details=db_fetch_array(db_query("select * from {users} where id=<USER_ID>"));


$user_details->hostname=$_SERVER['REMOTE_ADDR'];
$user_details->timestamp=time();
$user_details->roles=array('4'=>'client');


global $user;
$user=$user_details;

Explanation:

The idea is very simple. You just need to overwrite the $user variable with that in the database. So I simply fetch all the details of the user and put it in the $user variable. But just by doing this will not do the job, I also need to assign few extra variables such as the hostname, timestamp and roles. Hostname and timestamp are pretty much easy and self explanatory. What is vital is the roles variable given as:



$user_details->hostname=$_SERVER['REMOTE_ADDR'];  
$user_details->timestamp=time();  
$user_details->roles=array('4'=>'client');


If you do not assign role, the user will be logged in but wont be able to access any page of the website. So I created a role array containing the role id and its corresponding role name as:

$user_details->roles=array('ROLE_ID'=>'ROLE_NAME');
i.e.
$user_details->roles=array('4'=>'client');


and the user logs in.

Similarly if you want the user to logout forcefully, then simply empty the $user global array as follows:

global $user;
$user=array();

Hope this helps

3 comments:

  1. db_fetch_object instead of db_fetch_array.

    also do you by any chance know how to log a user (more like give name/uid/permissions/whatever) without having access to DB ? i will only have obcject/array from REST server, and with that data i have to log users.:)

    ReplyDelete
  2. It is given in the explanation above. Still the simplest solution is

    1. Use Drupal's default login
    2. display the $user array.
    3. Note down the array elements, specially the one's related to roles.

    Now for force login create the same array with your values and assign it to the global variable, $user.

    That's it.

    ReplyDelete
  3. ok, you're right of course but in your example you have used a db connection. Like i said i dont have that comfort :) and everytime i assigned object to $user variable i was logged in but it didnt keep that users sessions bcoz there was no user with such UID in {users} table.
    the way i did it was creating a table i called {users_sessions} which contains few basic fields for uesr recognition and session data holding. that way i can add session with user into one place not worying about no UID from one of the session queries. i also dont have to dynamically create/delete users i want to log in.

    ReplyDelete