Drupal login externally

Suppose we have a Drupal site and an external application, and we want to use the same login for both. For example, we have an application which does something, but we have our users handled by Drupal, and we need to pass over to the application the information about the current user.

Basically we need to tap into our Drupal's user database table. We also need to use Drupal's $_SESSION, but Drupal stores its sessions in the database by default, and the $_SESSION superglobal remains empty. Instead, we need to use the global $user variable.

Taking this one step further, why not synchronize the logins? By synchronize I mean if we log in into Drupal, we get logged automatically into the application, and vice-versa, when we log in the application, we get logged into the Drupal site automatically . That way, if we navigate from app to Drupal, we don't have to relogin.
Assuming your app and Drupal are hosted on the same machine and domain, check out the code which does all of this. <?php $drupal_path = 'full/path/to/drupal'; $drupal_url = 'http://site.com'; // no trailing slashes drupal_external_load($drupal_path, $drupal_url); // user is logged in into Drupal? if ( $user->uid > 0 ) { print 'user is logged'; } else { print 'user is not logged in'; } // use your app with a standalong login? // drupal_external_login('user', 'pass'); // make sure nothing gets sent to the browser before calling this function // if user logges out from your app, you might want to log out from Drupal too // drupal_external_logout(); // let's see what the global drupal user object looks like print '<pre>'.print_r($user, 1).'</pre>'; // load drupal stuff function drupal_external_load($drupal_path, $drupal_url) { global $base_url; // set drupal base_url (if not set set in settings.php) // because it's used in session name $base_url = $drupal_url; // save current path $current_path = getcwd(); // move to drupal path, because it uses relative path for its includes chdir($drupal_path); require_once './includes/bootstrap.inc'; // to use the drupal global user var (instead of session hack) drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION); // to have acess to full api //drupal_bootstrap(DRUPAL_BOOTSTRAP_FUL); // return the current path chdir($current_path); } // load a drupal user into the user obj function drupal_external_userload($user_info = array()) { // Dynamically compose a SQL query: $query = array(); $params = array(); if (is_numeric($user_info)) { $user_info = array('uid' => $user_info); } elseif (!is_array($user_info)) { return FALSE; } foreach ($user_info as $key => $value) { if ($key == 'uid' || $key == 'status') { $query[] = "$key = %d"; $params[] = $value; } else if ($key == 'pass') { $query[] = "pass = '%s'"; $params[] = md5($value); } else { $query[]= "LOWER($key) = LOWER('%s')"; $params[] = $value; } } $result = db_query('SELECT * FROM {users} u WHERE '. implode(' AND ', $query), $params); if ($user = db_fetch_object($result)) { $user = drupal_unpack($user); $user->roles = array(); if ($user->uid) { $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; } else { $user->roles[DRUPAL_ANONYMOUS_RID] = 'anonymous user'; } $result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid); while ($role = db_fetch_object($result)) { $user->roles[$role->rid] = $role->name; } //user_module_invoke('load', $user_info, $user); } else { $user = FALSE; } return $user; } // don't send any headers before calling this function drupal_external_login($username, $password) { global $user; if ( $user->uid > 0 ) { if ( $user->name != $username ) { drupal_external_logout(); } else { return true; } } $query = db_query("SELECT uid FROM {users} WHERE name LIKE '%s' AND pass LIKE '%s' AND status =1", $username, md5($password) ); $uid = db_result($query); if ( $uid ) { $user = drupal_external_userload(1); sess_regenerate(); return true; } return false; } function drupal_external_logout() { global $user; session_destroy(); $user = drupal_anonymous_user(); } ?>