如何以编程方式登录用户?


41

我正在寻找让我通过传递用户名和密码来登录用户的API。有人对此有经验吗?

为了澄清,我试图制作一个AJAX登录框,该框在主页上显示为弹出窗口,并且在凭据错误的情况下不刷新页面,但前提是登录正确。所以这是我到目前为止所做的:

更新资料

现在,我将登录表单加载到我的主页上,然后在提交时启动一个AJAX请求,该请求将凭证发送到此脚本:

function user_login_submit_try() {
  global $user;  

  $uid = user_authenticate($_POST['name'],$_POST['pass']);    
  $arr = array ('name'=>$_POST['name'],'pass'=>$_POST['pass']);
  if ($uid){
    $user = user_load($uid);
    user_login_finalize($arr);
  }

  echo drupal_json_encode($uid); 
  exit;
}; 

到目前为止,它仍然有效,但是我担心的是(如googletorp所述)安全问题;似乎我在此脚本中使用的任何API都没有对数据进行消毒。

会有人看到更好的方法吗?


由于什么原因,您需要使用用户名和密码从代码中登录用户?
kiamlaluno

@ kiamlaluno因为我需要在登录表单上使用Ajax。在我的先例问题:drupal.stackexchange.com/questions/5780/... drupal.stackexchange.com/questions/5781/...我解决不了任何的这两个问题,所以我去了一个自定义的Ajax请求。
silkAdmin 2011年

Answers:


33

这可能会帮助某人:

function mymodule_user_login_credentials($username, $password)
{
    if(user_authenticate($username, $password))
    {
      $user_obj = user_load_by_name($username);
      $form_state = array();
      $form_state['uid'] = $user_obj->uid;      
      user_login_submit(array(), $form_state);
      return true;
    }
    else
    {
        return false;
    }
}

根据评论的更好的版本:

function mymodule_user_login_credentials($username, $password)
{
    if($uid = user_authenticate($username, $password))
    {
      user_login_submit(array(), array('uid' => $uid));
      return true;
    }
    else
    {
        return false;
    }
}

3
user_authenticate已经返回了$ uid,因此无需加载用户对象;)
FLY

7
第二个代码块将不起作用;user_login_submit的第二个arg由ref传递;将其传递给array()的输出将失败。
肖恩·康

使用注册表格创建用户后,如何使用此答案自动登录用户?我想这样做,但是当通过account对象作为参数提供密码时,密码是一个哈希,hook_user_insert但是答案中的上述功能希望密码为原始纯文本。我想我需要尝试hook_form_alter...
therobyouknow

对于在创建新用户后立即寻求自动登录的人们(例如,通过用户注册注册表,例如“用户/注册”),请参阅以下解决方案:drupal.stackexchange.com/a/254905/1082
therobyouknow

19

没有简单的API函数。

您可以执行Drupal的操作:

  1. 通过查询数据库来测试密码,请参见:

user_login_name_validate()
user_login_authenticate_validate()
user_login_final_validate()

  1. 覆盖global $user

    global $user;
    $user = user_load($uid);
  2. 处理会议

user_login_finalize($form_state);

对于第二步和第三步,请参见 user_login_submit()

所有这些功能都是基于从表单调用的。正常流程是验证处理程序测试用户输入,如果通过验证,则返回用户的uid。然后,提交处理程序将处理用户的实际登录并调用用户挂钩。


谢谢googletorp,我将尝试一下,尽管这让我想知道此功能如何协同工作。.一个人怎么知道我确实援引了先例?
silkAdmin 2011年

哦,如果我没有From_state变量可用,而只有用户名和密码可用,我可以像$form_state['value']['name'] = $_POST['name']这样重建它

@silk您应该始终使用为您提供$form_state变量的Drupal FAPI 。有很多不错的安全检查,否则它们可能会松开并可能打开站点进行攻击。在登录用户时,您不想失去这种安全性。
googletorp

请检查我更新的问题,我真的很想知道我的输入内容是否得到清理。.感谢
silkAdmin 2011年

抱歉,该编辑第一次无法使用,现在已更新。
silkAdmin 2011年

7

如果需要获取您知道用户名和密码的用户帐户的用户对象,则可以使用以下代码:

function mymodule_get_user(name, $password) {
  $account = FALSE;

  if ($uid = user_authenticate($name, $password)) {
    $account = user_load($uid);
  }

  return $account;
}

$account将是FALSE如果用户对象不能找到或加载。

例如,当您的模块从用户获得输入的用户名和密码,验证它们是否正确,然后对用户对象执行某些操作时,应使用此代码。
如果您要编写的模块需要冒充用户写评论,或者要执行其他需要由用户完成的操作,这就是项目问题跟踪模块在关闭已存在的问题报告时所做的工作固定状态两周(在这种情况下,它会添加注释“自动关闭-问题已修复两周,没有活动”,该结果由“系统消息”用户编写),那么您不需要用户名和密码。您只需加载知道其用户ID的用户对象。

据我所知,我报告的代码没有任何安全性问题。
您可能想限制登录失败的次数;或暂时阻止尝试成功登录的IP,或在短时间内尝试其他登录。


谢谢kiamlaluno,这是我的工作,但我现在担心安全问题,请查看我更新的问题
silkAdmin 2011年

3

该代码确实有效

//login
$uid = user_authenticate($username, $password);
global $user;
$user = user_load($uid);    
//login finalize
watchdog('remote_user', 'Session opened for %name.', array('%name' => $user->name));
$user->login = REQUEST_TIME;
db_update('users')
  ->fields(array('login' => $user->login))
  ->condition('uid', $user->uid)
  ->execute();
drupal_session_regenerate();

它不会调用hook_user_login,请参阅user_login_finalize()函数。
skorzh '16

2

从上面清理答案。检查用户和密码是一项附加功能。另外,假form_state必须是要通过引用传递给函数的变量,否则会引发错误。

因此,我们有:

function mymodule_log_in_by_uid($uid) {
    $faux_form_state = array('uid' => $uid);
    user_login_submit(array(), $faux_form_state);
}

0

该用户将收到该会话,并且还将登录到其他页面:

function custom_log_in_by_uid($uid) {
    $form_state = array('uid' => $uid);
    user_login_submit(array(), $form_state);
}

0

有时我们需要通过URL或忘记管理员密码快速登录。只需实现以下两个功能即可在Drupal中以用户1身份登录。

function mymodule_menu(){
    $items['login/as/admin'] = array(
        'title' => 'Login as admin account',
        'page callback' => 'mymodule_login_as_admin',
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    return $items;
}
function mymodule_login_as_admin(){
    global $user;
    $user = user_load(1);
    return "Global user set as admin. Please refresh page ";
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.