Як я можу програмно увійти до користувача?


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

Відповіді:


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
Другий блок коду не буде працювати; 2-й аргумент user_login_submit передається за допомогою ref; передаючи його, вихід масиву () не вдасться.
Шон Конн

Як ця відповідь буде використана для автоматичного входу користувача після їх створення за допомогою реєстраційної форми? Я хотів би це зробити, але пароль - хеш, коли він надається через об’єкт облікового запису як параметр у, 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);

Крок другий та 3 див user_login_submit()

Усі ці функції засновані на виклику з форми. Нормальний потік полягає в тому, що перевірені обробники перевіряють введення користувачів і повертають uid користувача, якщо перевірка проходить. Потім обробник подання обробляє фактичне вхід користувача та виклик гака користувача.


дякую googletorp, я спробую це, хоча це дозволить мені задатися питанням, як ці функції працюють разом .. Як можна знати, що я посилався на прецедент?
silkAdmin

ой, і якщо у мене немає доступної змінної From_state, а лише ім'я користувача та пароль, чи можу я відновити її так: $form_state['value']['name'] = $_POST['name']і так далі ..
silkAdmin

@silk Ви завжди повинні використовувати FTPI Drupal, який дає вам $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();

Він не викликає прив'язку_користувача, див. Функцію 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 ";
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.