2

我只是 Drupal 的新手,但我想让我的网站通过外部登录源进行身份验证。我的意思是,不要使用当前的 Drupal 数据库登录。然后使用一个或多个外部数据库。

为了更清楚一点:

  • 用户登录验证不会使用现有的 Drupal 数据库。
  • 然后它将使用外部数据库
  • 外部数据库将是一个或多个(如果在一个外部数据库上找不到用户,则在另一个源上再次找到。)

我一直在尝试破解 Drupal 登录,但由于结构足够复杂,我还做不到。请问有什么解决方案或建议吗?

  • 需要修改哪些文件?
4

2 回答 2

4

您不应该为此完全放弃 Drupal 的用户系统,而应该使用您自己的身份验证对其进行尾随。其工作方式是 1) 收集用户凭据,2) 针对您的自定义源进行身份验证,以及 3) 注册/登录外部用户。

收集凭据

收集用户凭据的一种方法是劫持用户登录表单。您可以通过实现hook_form_alter()和添加自己的验证回调来做到这一点。

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['#validate'][] = array('mymodule_user_login_validate');
    $form['#validate'][] = array('mymodule_user_login_submit');
  }
}

登录表单看起来完全一样,但它会将用户名和密码发送到您的回调。

user_login_name_validate()user_login_final_validate()回调是 user.module 的默认验证器。它们提供用户阻止功能和蛮力保护,但可以随意将它们排除在外。

验证

发送登录表单后,您将获取凭据并针对您的自定义来源进行身份验证。

function mymodule_user_login_validate($form, &$form_state) {
  mymodule_authenticate(
    $form_state['values']['name'],
    $form_state['values']['name']
  );
}

如果凭据没有签出,您可以打电话form_set_error()通知用户出了什么问题。这样做还可以确保不会执行进一步的验证或提交回调。

外部用户

因此,如果没有引发错误,则 Drupal 将继续运行您的提交回调。然后我们可以运行user_external_login_register()以将我们的外部用户创建为 Drupal 用户。

function mymodule_user_login_submit($form, &$form_state) {
  user_external_login_register($form_state['values']['name'], 'mymodule');
}

顾名思义,这个功能也会让用户登录。应该就是这样!

有一个模块

很可能已经有一个模块可以用于您想要做的事情。在开始你自己的之前总是去搜索现有的贡献模块!

于 2012-06-30T14:50:33.017 回答
2
define('DRUPAL_ROOT',  'full/path/to/drupal');
$drupal_url  = 'http://site.com';
drupal_external_load($drupal_path, $drupal_url);

if ( !($user->uid > 0) ) {
  drupal_external_login('user', 'pass');  
} else {
  print 'user is already logged';
}

function drupal_external_load($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_ROOT);

  require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  // to use the drupal global user var (instead of session hack)
  // drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
  // 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;
    }
  }

  require DRUPAL_ROOT. '/includes/password.inc' ;

  $account = user_load_by_name($username);

  if ( user_check_password($password, $account) ) {

    $user = $account;
    drupal_session_regenerate();
    return true;
  }
  return false;
}

function drupal_external_logout() {

  global $user;
  session_destroy();
  $user = drupal_anonymous_user();
}
于 2013-07-02T06:05:18.153 回答