Как программно войти в систему пользователя?

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, который я использовал в этом скрипте, не очистил данные в любом случае.

Кто-нибудь увидит лучший способ сделать это?

silkAdmin
источник
По какой причине вам нужно будет войти в систему пользователя из кода, используя имя пользователя и пароль?
kiamlaluno
@ kiamlaluno Потому что мне нужно использовать Ajax в форме входа. В моих прецедентных вопросах: drupal.stackexchange.com/questions/5780/… drupal.stackexchange.com/questions/5781/… Я не смог решить ни одну из этих двух проблем, поэтому я пошел за пользовательским запросом ajax.
silkAdmin

Ответы:

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;
    }
}
user1750
источник
3
user_authenticate уже возвращает $ uid, поэтому нет необходимости загружать пользовательский объект;)
FLY
7
Второй блок кода не будет работать; 2-й аргумент user_login_submit передается ref; передать его вывод array () не удастся.
Шон Конн
Как этот ответ будет использоваться для автоматического входа пользователя после того, как он был создан с помощью регистрационной формы? Я хотел бы сделать это, но пароль является хешем, когда предоставляется через объект учетной записи в качестве параметра в, 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);

Шаг 2 и 3 см. user_login_submit()

Все эти функции основаны на вызове из формы. Обычный процесс заключается в том, что обработчики проверки проверяют вводимые пользователем данные и возвращают идентификатор пользователя, если проверка прошла успешно. Затем обработчик отправки обрабатывает фактический вход пользователя в систему и вызов пользователя.

googletorp
источник
спасибо googletorp, я попробую это, хотя это позволяет мне задаться вопросом о том, как эти функции работают вместе. Как узнать, что я вызывал прецедент?
silkAdmin
о, и если у меня нет доступной переменной From_state, а есть только имя пользователя и пароль, могу ли я перестроить ее следующим образом: $form_state['value']['name'] = $_POST['name']и т. д.
silkAdmin
@silk Вы всегда должны использовать Drupal FAPI, который дает вам $form_stateпеременную. Есть много хороших проверок безопасности, которые вы могли бы в противном случае потерять и открыть свой сайт для атак. Когда дело доходит до входа пользователя, вы не хотите терять эту безопасность.
googletorp
Пожалуйста, проверьте мой обновленный вопрос, я действительно хотел бы знать, очищены ли мои входные данные .. Спасибо
silkAdmin
Извините, похоже, что редактирование не сработало в первый раз, теперь оно обновлено.
silkAdmin
7

Если вам нужно получить объект пользователя для учетной записи, для которой вы знаете имя пользователя и пароль, то вы можете использовать следующий код:

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

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

  return $account;
}

$accountбудет, FALSEесли пользовательский объект не может быть найден или загружен.

Вы должны использовать этот код, когда, например, ваш модуль получает имя пользователя и пароль в качестве ввода от пользователя, он проверяет, верны ли они, и затем что-то делает с объектом пользователя.
Если вы пишете модуль, которому нужно выдать себя за пользователя, чтобы написать комментарий, или делаете что-то еще, что должно получиться так, как это делает пользователь, что и делает модуль отслеживания проблем проекта при закрытии отчета о проблеме, который был в фиксированный статус на две недели (в этом случае добавляется комментарий «Автоматически закрыто - проблема исправлена ​​на 2 недели без активности», в результате чего пользователь «Системное сообщение» пишет), тогда вам не нужны имя пользователя и пароль. Вы просто загружаете пользовательский объект, для которого вы знаете идентификатор пользователя.

Насколько я знаю, с кодом, о котором я сообщил, проблем безопасности нет.
Вы можете ограничить количество неудачных входов в систему; или временно заблокировать IP-адрес, который пытается войти в систему безуспешно или пытается выполнить другой вход в систему в течение короткого времени.

киамлалуно
источник
спасибо kiamlaluno, это вроде того, что я сделал, но сейчас я беспокоюсь о проблемах безопасности, пожалуйста, проверьте мой обновленный вопрос
silkAdmin
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();
Vacho
источник
Он не вызывает hook_user_login, см. Функцию user_login_finalize ().
Скорж
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 или забытый пароль администратора. Просто реализуйте ниже две функции, чтобы войти как пользователь 1 в Drupal.

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 ";
}
Гириш Батьял
источник