1

I am currently using the services module and some custom code to delete, login and edit drupal users from an external application. I can currently login as a user on the external application but I am only logged on in the code and not the actual browser. Meaning that I can perform actions with the authenticated account in the code but when I visit my drupal website through the browser, I am not logged in. I want my users to be logged into drupal when they log into my external application. How can I do this?

2

You can use the form API to write a custom function for validating authentication. Something like this (this is from Drupal 7, but for 6 you have the same logic and the API is not very different). The code here is from a module I've wrote to authenticate users from an IP.Board (a forum software) database:

<?php
/**
 * @file
 * Allow Drupal 7 to use IP.Board members table for authentication
 *
 * Some code is based on this nice tutorial http://www.touchnoc.com/node/86
 */

/**
 * Alter the user login block form
 */
function ipbridge_form_user_login_block_alter(&$form, &$form_state) {
  _ipbridge_user_login_form_alter($form, $form_state);
}

/**
 * Alter the user login page
 */
function ipbridge_form_user_login_alter(&$form, &$form_state) {
  _ipbridge_user_login_form_alter($form, $form_state);
}

/**
 * Change the validate callback
 */
function _ipbridge_user_login_form_alter(&$form, &$form_state) {
  $k = array_search('user_login_authenticate_validate', $form['#validate']);
  $form['#validate'][$k] = 'ipbridge_authenticate_validate';
}


/**
 * Custom validation
 */
function ipbridge_authenticate_validate($form, &$form_state) {

  // try normal validation first
  user_login_authenticate_validate($form, $form_state);
  if ($form_state['uid'] !== FALSE)
    return;

  // still here? Try to find the user in IP.Board
  $name = $form_state['values']['name'];
  $pass = $form_state['values']['pass'];

  $records = db_select('ibf_members', 'u', array('target' => 'ipb'))
  ->fields('u', array('member_id', 'name', 'members_pass_hash', 'members_pass_salt', 'email'))
  ->condition('u.name', $name, '=')
  ->execute();

  if ($records->rowCount() == 1) {

    $ipbUser = $records->fetchObject();

    // this is how IPB generates the pasword hash
    $hash = md5(md5($ipbUser->members_pass_salt) . md5($pass));

    if ($hash == $ipbUser->members_pass_hash) {

      // based on Drupal's user_external_login_register (that function doesn't set the email address)
      $account = user_external_load($name);
      if (!$account) {

        $userinfo = array(
          'name' => $name,
          'mail' => $ipbUser->email,
          'pass' => user_password(),
          'init' => $name,
          'status' => 1,
          'access' => REQUEST_TIME,
        );

        try {
          $account = user_save(drupal_anonymous_user(), $userinfo);
        } catch (Exception $e) {
          drupal_set_message(t('Are you trying to login using an IP.Board username that was previously registered in Drupal? Caught exception: ' . $e->getMessage()), 'error');
        }

        if (!$account) {
          drupal_set_message(t("Error saving IPB account."), 'error');
          $form_state['uid'] = FALSE;
          return;
        }
        user_set_authmaps($account, array("authname_ipbridge" => $name));
      }

      $form_state['uid'] = $account->uid;
    }
  }
}
?>
  • This is part of what I want to do but the other part is logging into drupal whenever someone logs into the external app – Matthew Hui May 30 '11 at 16:52
  • If you want to handle this in a Drupal module you need to have the user registered in Drupal (the code I've sent you does this) and then check if the user is logged in your application and call user_external_load() and user_external_login(). Check api.drupal.org/api/drupal/modules--openid--openid.module/6/… for an example. If you don't have any way to check in a Drupal module if the user is authenticated in your external application, then this is another approach that can be used on your application side: mugginsoft.com/content/… – Stefan May 31 '11 at 15:54
  • I tried the second option but it only authenticates for 1 page – Matthew Hui Jun 2 '11 at 2:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.