Question

Supposons que j'ai une instruction SQL comme celle-ci qui vérifie le login d'un utilisateur:

SELECT * FROM users 
WHERE username='test@example.com', password='abc123', expire_date>=NOW();

Existe-t-il un moyen en SQL de déterminer précisément quelles conditions WHERE échouent, sans avoir à séparer chaque condition dans sa propre requête et à tester individuellement?

Dans cet exemple spécifique, le développeur pourrait indiquer aux utilisateurs exactement la raison de l'échec de la tentative de connexion.

Pour mes besoins, j'utilise PHP / MySQL.

Était-ce utile?

La solution 5

Voici ce que j'ai créé:

SELECT
  IF(mem_username='test@example.com','true','Error: Bad Username') AS mem_username,
  IF(mem_password ='abc123','true','Error: Bad Password') AS mem_password'
FROM MEMBERS
WHERE mem_username='test@example.com' AND mem_password='abc123'

De cette façon, je peux détecter dans le code les messages d'erreur et les afficher si nécessaire.

REMARQUE: À vous tous, citant des problèmes de sécurité avec l'exemple de code, merci de votre préoccupation. Cependant, ce n’est pas un code de production réel, c’était simplement un exemple simple pour illustrer la question que j’avais. Il est bien évident que vous ne devez pas stocker les mots de passe en texte clair ni donner aux utilisateurs des informations sur les raisons de l'échec de la connexion.

Autres conseils

Eh bien, vous pouvez modifier votre requête afin qu'elle ne corresponde qu'au nom d'utilisateur. Ensuite, dans le code, vous vérifiez le mot de passe et la date d'expiration, en renvoyant les erreurs appropriées.

De plus, j'espère que votre exemple de requête est une simplification. Vous devriez certainement saler / chiffrer / hacher vos mots de passe et inclure quelque chose qui limite le nombre de tentatives infructueuses dans un délai donné, etc.

En ce qui concerne votre question (par opposition aux résultats que vous recherchez), il n’est pas possible d’obtenir ces informations à partir de la clause where. Le plus proche que vous puissiez faire serait quelque chose comme:

SELECT *,
    CASE WHEN Password = 'asdf' THEN 1 ELSE 0 END AS IsPasswordMatch,
    CASE WHEN Expiration >= NOW() THEN 1 ELSE 0 END AS IsActiveAccount
FROM Users
WHERE Username = 'user'

Dans MySQL, vous pouvez insérer des expressions booléennes dans la liste de sélection. Les expressions booléennes correspondent à 1 si vrai ou à 0 si faux.

SELECT password = 'abc123' AS is_authenticated,
       expire_date >= NOW() AS is_not_expired
FROM users
WHERE username='test@example.com';

Remarque: Si vous devez rédiger une requête qui fonctionne sur d'autres marques de SGBDR, n'oubliez pas que l'utilisation d'expressions booléennes n'est pas standard. Utilisez la syntaxe CASE que d'autres personnes ont publiée.

PS: Ceci est une tangente de votre question, mais je vous exhorte à ne pas stocker les mots de passe en texte clair. Stocker un condensé de hachage du mot de passe salé. Voir Comment le sel de mot de passe aide-t-il à lutter contre une attaque de table arc-en-ciel?

Non, la clause where est appliquée en tant que bloc et diverses techniques sont utilisées pour éviter que toutes les lignes ne soient analysées. En outre, comment sauriez-vous quelle rangée était celle souhaitée?

De plus, vous ne voudrez probablement pas trop expliquer à l'utilisateur pourquoi une tentative de connexion a échoué. En dire trop autorise des exploits tels que l'exploration de compte et les attaques par mot de passe.

modifier Si vous souhaitez vraiment afficher cette information à votre utilisateur, divisez votre logique en différentes parties:

  1. Valider l'identité
    Action: Récupérez la ligne utilisateur correspondante dans la base de données.
    Résultat:
    • Si aucune ligne de ce type n'existe = > compte invalide
    • Si la ligne est renvoyée, passez à l'étape 2.
  2. Valider les informations d'identification
    Action: Vérifiez les informations d'identification stockées (mot de passe, mot de passe haché ou mot de passe crypté) par rapport au mot de passe fourni traité de la même manière que les informations d'identification sont stockées.
    Résultat:
    • Pas de correspondance = > Mot de passe / identifiant invalide
    • Correspondance = > Tentative de connexion réussie
  3. Utilisateur de connexion
    Action: ajouter des données à la session, etc.

Vous avez probablement juste besoin de séparer les parties de la clause where avec 'AND'

SELECT * FROM users 
WHERE username='test@example.com'
   And password='abc123'
   And expire_date>=NOW();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top