我只是 Drupal 的新手,但我想让我的网站通过外部登录源进行身份验证。我的意思是,不要使用当前的 Drupal 数据库登录。然后使用一个或多个外部数据库。
为了更清楚一点:
- 用户登录验证不会使用现有的 Drupal 数据库。
- 然后它将使用外部数据库
- 外部数据库将是一个或多个(如果在一个外部数据库上找不到用户,则在另一个源上再次找到。)
我一直在尝试破解 Drupal 登录,但由于结构足够复杂,我还做不到。请问有什么解决方案或建议吗?
- 需要修改哪些文件?
您不应该为此完全放弃 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');
}
顾名思义,这个功能也会让用户登录。应该就是这样!
很可能已经有一个模块可以用于您想要做的事情。在开始你自己的之前总是去搜索现有的贡献模块!
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();
}