Pergunta

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?

Foi útil?

Solução

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;
    }
  }
}
?>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a drupal.stackexchange
scroll top