2

私は Drupal の初心者ですが、サイトを外部ログイン ソースから認証できるようにしたいと考えています。つまり、現在の Drupal データベースを使用してログインしないということです。次に、1 つ以上の外部データベースを使用します。

もう少し明確にするために:

  • ユーザー ログイン認証は、既存の Drupal データベースを使用しません。
  • 次に、外部データベースを使用します
  • 外部データベースは 1 つ以上になります (ユーザーが 1 つの外部データベースで見つからない場合は、別のソースで再度見つかります)。

Drupal ログインのハッキングを試みていますが、構造が複雑すぎてまだできません。解決策や提案はありますか?

  • どのファイルを変更する必要がありますか?
4

2 に答える 2

4

このために Drupal のユーザー システムを完全に破棄するのではなく、独自の認証を使用してそれにピギー テールを適用する必要があります。これが機能する方法は、1) ユーザー資格情報の収集、2) カスタム ソースに対する認証、および 3) 外部ユーザーの登録/ログインです。

資格情報の収集

ユーザー資格情報を収集する 1 つの方法は、ユーザー ログイン フォームをハイジャックすることです。これを行うには、独自の検証コールバックを実装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');
}

名前が示すように、この関数はユーザーのログインも行います。

そのためのモジュールがあります

あなたがやりたいことのためのモジュールがすでにある可能性があります。独自のモジュールを開始する前に、必ず既存の contrib モジュールを検索してください!

于 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 に答える