Comment enregistrer par programme un utilisateur?

41

Je recherche l'API qui me permettra de connecter un utilisateur en lui transmettant le nom d'utilisateur et le mot de passe. Est-ce que quelqu'un a de l'expérience avec ça?

Pour clarifier les choses, j'essaie de créer une boîte de connexion AJAX qui s'affiche sous forme de fenêtre contextuelle sur la page d'accueil et de ne pas actualiser la page en cas d'informations erronées, mais uniquement si la connexion est correcte. Alors voici ce que j'ai fait jusqu'à présent:

Mise à jour

Je charge maintenant le formulaire de connexion sur ma page d'accueil, puis lors de la soumission, je lance une demande AJAX qui envoie les informations d'identification à ce script:

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;
}; 

Jusqu'à présent, cela fonctionne, mais mes inquiétudes sont (comme mentionné par googletorp) des problèmes de sécurité; il semble qu'aucune des API que j'ai utilisées dans ce script ne désinfecte les données de toute façon.

Quelqu'un verrait-il un meilleur moyen de le faire?

silkAdmin
la source
Pour quelle raison auriez-vous besoin de connecter un utilisateur à partir du code en utilisant nom d'utilisateur et mot de passe?
kiamlaluno
@ kiamlaluno Parce que je dois utiliser Ajax sur le formulaire de connexion. Dans mes questions précédentes: drupal.stackexchange.com/questions/5780/… drupal.stackexchange.com/questions/5781/… Je ne pouvais résoudre aucun de ces deux problèmes, j'ai donc opté pour une demande ajax personnalisée.
silkAdmin

Réponses:

33

Cela pourrait aider quelqu'un:

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;
    }
}

Une meilleure version basée sur le commentaire:

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;
    }
}
utilisateur1750
la source
3
user_authenticate renvoie déjà le $ uid, il n'est donc pas nécessaire de charger l'objet utilisateur;)
FLY
7
Le deuxième bloc de code ne fonctionnera pas; Le 2ème argument de user_login_submit est passé par ref; en passant la sortie de array () échouera.
Shawn Conn
Comment cette réponse serait-elle utilisée pour connecter automatiquement un utilisateur après sa création à l'aide d'un formulaire d'inscription? J'aimerais faire cela, mais le mot de passe est un hachage lorsqu'il est fourni via l'objet de compte en tant que paramètre dans, hook_user_insertmais les fonctions ci-dessus dans la réponse veulent le mot de passe comme texte brut d'origine. J'imagine que je vais devoir essayer à la hook_form_alterplace ...
therobyouknow
Pour les personnes recherchant une connexion automatique directement après la création du nouvel utilisateur (par exemple via un formulaire d'inscription, par exemple "utilisateur / registre"), voir la solution suivante: drupal.stackexchange.com/a/254905/1082
therobyouknow
19

Il n'y a pas une fonction API simple pour cela.

Vous pouvez faire ce que Drupal fait:

  1. Testez le mot de passe en interrogeant la base de données, voir:

user_login_name_validate ()
user_login_authenticate_validate ()
user_login_final_validate ()

  1. Écraser le global $user.

    global $user;
    $user = user_load($uid);
  2. Gérer les sessions

user_login_finalize($form_state);

Pour les étapes deux et 3, voir user_login_submit()

Toutes ces fonctions sont basées sur l’appel depuis un formulaire. Le flux normal est que les gestionnaires de validation testent l'entrée de l'utilisateur et renvoient l'identifiant de l'utilisateur si la validation réussit. Le gestionnaire d'envoi gère ensuite la connexion réelle de l'utilisateur et le raccordement de l'utilisateur appelant.

googletorp
la source
merci googletorp, je vais essayer ça, bien que cela me laisse penser à la façon dont cela fonctionne ensemble .. Comment savoir si j'ai invoqué le précédent?
silkAdmin
oh et si je n'ai pas la variable From_state disponible mais juste le nom d'utilisateur et le mot de passe, puis-je le reconstruire comme $form_state['value']['name'] = $_POST['name']
suit
@silk Vous devriez toujours utiliser le FAPI Drupal qui vous donne la $form_statevariable. Il existe de nombreuses vérifications de sécurité intéressantes que vous auriez sinon perdues et qui pourraient permettre à votre site d’être attaqué. Lorsque vous vous connectez à un utilisateur, vous ne voulez pas perdre cette sécurité.
googletorp
S'il vous plaît vérifier ma question mise à jour, je voudrais vraiment savoir si mes entrées sont nettoyées .. Merci
silkAdmin
Désolé, il semble que l'édition n'ait pas fonctionné la première fois. Elle est maintenant mise à jour.
silkAdmin
7

Si vous devez obtenir l'objet utilisateur du compte d'utilisateur pour lequel vous connaissez le nom d'utilisateur et le mot de passe, vous pouvez utiliser le code suivant:

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

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

  return $account;
}

$accountsera FALSEsi l'objet utilisateur ne peut pas être trouvé ou chargé.

Vous devez utiliser ce code lorsque, par exemple, votre module obtient le nom d'utilisateur et le mot de passe saisis par un utilisateur, vérifie s'ils sont corrects et effectue ensuite quelque chose avec l'objet utilisateur.
Si vous écrivez un module qui doit emprunter l'identité d'un utilisateur pour rédiger un commentaire, ou effectuez une autre opération qui doit être effectuée par un utilisateur, comme le fait le module de suivi des problèmes de Project lors de la fermeture d'un rapport de problème figurant dans le dossier. statut fixe pendant deux semaines (dans ce cas, il ajoute le commentaire "Fermé automatiquement - problème résolu pendant deux semaines sans activité" avec les résultats écrits par l'utilisateur "Message système"), vous n'avez pas besoin de nom d'utilisateur ni de mot de passe. Vous venez de charger l'objet utilisateur pour lequel vous connaissez l'ID utilisateur.

Autant que je sache, le code que j'ai rapporté ne présente aucun problème de sécurité.
Vous voudrez peut-être limiter le nombre de connexions échouées; ou de bloquer temporairement l'IP qui tente de se connecter sans succès ou tente plusieurs connexions en peu de temps.

kiamlaluno
la source
merci kiamlaluno, c'est un peu ce que j'ai fait, mais je m'inquiète maintenant pour des problèmes de sécurité, consultez ma question mise à jour
silkAdmin le
3

Ce code fonctionne vraiment

//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
la source
Il n'appelle pas hook_user_login, voir la fonction user_login_finalize ().
Skorzh
2

Réponse nettoyée de ce qui précède. La vérification de l'utilisateur et du mot de passe est une fonctionnalité supplémentaire. De plus, le faux état de formulaire doit être une variable à transmettre par référence à la fonction ou une erreur est générée.

Nous avons donc:

function mymodule_log_in_by_uid($uid) {
    $faux_form_state = array('uid' => $uid);
    user_login_submit(array(), $faux_form_state);
}
Jeremy John
la source
0

L'utilisateur recevra la session et sera également connecté à d'autres pages:

function custom_log_in_by_uid($uid) {
    $form_state = array('uid' => $uid);
    user_login_submit(array(), $form_state);
}
Віктор Плясун
la source
0

Parfois, nous avons besoin d'une connexion rapide à partir d'une URL ou d'un mot de passe administrateur oublié. Il vous suffit de mettre en œuvre ci-dessous deux fonctions pour vous connecter en tant qu'utilisateur 1 dans 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 ";
}
Girish Bathyal
la source