Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Logowanie username or email
Forum PHP.pl > Forum > PHP
MESSIAH :)
Jak poprawnie wywołać kod do logowania przy użyciu nazwy użytkownika lub emaila?
  1. if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
  2. FROM members
  3. WHERE email = ? LIMIT 1")) {

zmieniam na
  1. if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
  2. FROM members
  3. WHERE email = ? OR username = ? LIMIT 1")) {


Lecz wciąż nie działa przy użyciu username i nie można zalogować po nazwie użytkownika.
rad11
Moze wina jest to ze robisz tak:

  1. if($stmt = $mysqli->prepare("SELECT id, username, password, salt
  2. FROM members
  3. WHERE email = ? LIMIT 1")){
  4. }


Zrob tak:

  1. $stmt = $mysqli->prepare("SELECT id, username, password, salt
  2. FROM members
  3. WHERE email = ? LIMIT 1");
  4.  
  5. $query = $stmp->execute();
  6.  
  7. if($query > 0){
  8. echo 'Istnieje wiec logujemy';
  9. }
MESSIAH :)
Jeśli zmienię email na username tutaj:
  1. FROM members
  2. WHERE email = ? LIMIT 1")){
  3. }

Wtedy będę mógł się zalogować po nazwie użytkownika więc tutaj muszę dodać jakis parametr który będzie wybierał pomiędzy username lub mail.
rad11
to takie zapytanie zrob ja napisalem przykladowo to zapytanie chodzilo mi o to ze execute nie robisz pierw.
MESSIAH :)
Nie rozumiemy się chyba. Ja chce przerobić zapytanie do bazy danych tak aby użytkownik podczas logowania mógł podać username lub email aby sie zalogować.
sazian
  1. $stmt = $mysqli->prepare("SELECT id, username, password, salt
  2. FROM members
  3. WHERE email = ? OR username = ? LIMIT 1")
  4. $stmt->bind_param('ss', $login_lub_email, $login_lub_email);
zidek
Pobieranie hasła z bazy jest raczej niepotrzebne, przecież tego hasła i tak nie będziesz do niczego potrzebował.
Przed wykonaniem zapytania powinieneś na poziomie PHP dokonać walidacji maila. Jeśli ma prawidłową formę wysyłasz zapytanie z warunkiem "WHERE email = '{$login}'", a jeśli nie "WHERE username = '{$login}'"
com
Cytat
Pobieranie hasła z bazy jest raczej niepotrzebne, przecież tego hasła i tak nie będziesz do niczego potrzebował.

Przy logowaniu? raczej powinien je sprawdzić czy sie zgadza z tym co podał ? wink.gif
Pyton_000
Tak, ale można to sprawdzić w zapytaniu smile.gif
sowiq
Cytat(Pyton_000 @ 12.01.2015, 11:09:19 ) *
Tak, ale można to sprawdzić w zapytaniu smile.gif

Oho, ktoś tu nie soli haseł wink.gif
phpion
@Pyton_000: Ale w takim przypadku zamykasz sobie drogę na informację zwrotną dlaczego użytkownik się nie zalogował. Bo wpisał niepoprawne hasło? Bo jego konto jest nieaktywne? Bo ma jakąś inną flagę ustawioną? Ja też wyciągam dane na podstawie loginu, a potem w PHP porównuję pozostałe parametry.

@MESSIAH: Co do pytania to proponuję dynamicznie podmieniać kolumnę na podstawie tego, co przesłał użytkownik. Jeśli jest to prawidłowy adres e-mail (można skorzystać z filter_var z flagą FILTER_VALIDATE_EMAIL) - użyj kolumny email, jeśli nie - username. Nie bawiłbym się w żadne ORy bo to skutecznie uniemożliwi użycie indeksu. W zaproponowanym przeze mnie rozwiązaniu jest 1 minus - przypadek, gdy nazwa użytkownika jest adresem e-mail, a podany adres e-mail jest inny smile.gif no ale to raczej mało realny przypadek.
Pyton_000
Dlaczego? Generuję sobie hash z hasła i sprawdzam czy taki hash istnieje w BD łącznie z adresem email lub userem
czyli

Kod
WHERE pass = 'hash' AND (email = 'email' OR username = 'username);

Nie widzę w tym niczego strasznego.

[Edited] @up tak to prawda, ale nie zawsze potrzebuję takiej informacji. To już zależy od kontekstu gdzie i dlaczego tego używam.
Napisałem tylko że tak tez można smile.gif
phpion
Cytat(Pyton_000 @ 12.01.2015, 10:20:50 ) *
Nie widzę w tym niczego strasznego.

...poza sekwencyjnym skanowaniem tabeli smile.gif
sowiq
Cytat(Pyton_000 @ 12.01.2015, 11:20:50 ) *
Nie widzę w tym niczego strasznego.


A ja widzę. W ten sposób nie posolisz hasła.

PS. Mam nadzieję, że Twój 'hash' to nie sha1, albo co gorsza - md5.
phpion
@sowiq:
Chyba, że sól jest wspólna dla wszystkich użytkowników wink.gif
sowiq
Wspólna sól = brak soli.
Pyton_000
@sowiq tak czysto informacyjnie używam Crypt z możliwie najmocniejszym algorytmem dost. na serwerze toteż uważam solenie za zbędne (ew. sól ogólna jak phpion powiedział) i tak, nie jest to ani sha1 ani md5 wink.gif
sowiq
Bardzo dobrze, że używasz crypt.

Jeśli chodzi o sól, to trzeba sobie zadać pytanie po co w ogóle jest ona stosowana. Jedną z pierwszych odpowiedzi (przynajmniej moich) jest: żeby dwa takie same hasła miały w bazie różne hashe. Zarówno w przypadku braku soli jak i w przypadku soli wspólnej dla całej bazy, takie same hasła będą miały takie same hashe. W związku z tym, z całą odpowiedzialnością podtrzymuję co napisałem wcześniej: wspólna sól = brak soli.
Pyton_000
Ten argument do mnie trafia bo jest racjonalny i poprawny politycznie smile.gif
com
Pyton_000 zgadzam się można, ale ten oto programista robił to sposobem opisanym przez phpion, a ja odnosiłem się do tego przypadku, bo uwzględniając podane przez innych argumenty, też wydaje mi się on bardziej sensowny, bo skoro już generujemy funkcje skrótu, to ma być jakieś utrudnienie/zabezpieczenie a jak ma być to zwykły hash , to mając takie możliwości jak mamy teraz, jest on zbliżony w dużej mierze do efektu jakby to było zapisane plaintextem(no może trochę przesadziłem, bo trzeba mieć troche wiedzy), bo wygenerowanie kolizji w takim wypadku jest na pewno prawdopodobne. A sposób zidek nie podawał informacji takiej jak zapropoowałeś co wprowadzało użytkownika w błąd, stąd tez moja uwaga.
MESSIAH :)
Cytat
@MESSIAH: Co do pytania to proponuję dynamicznie podmieniać kolumnę na podstawie tego, co przesłał użytkownik. Jeśli jest to prawidłowy adres e-mail (można skorzystać z filter_var z flagą FILTER_VALIDATE_EMAIL) - użyj kolumny email, jeśli nie - username. Nie bawiłbym się w żadne ORy bo to skutecznie uniemożliwi użycie indeksu. W zaproponowanym przeze mnie rozwiązaniu jest 1 minus - przypadek, gdy nazwa użytkownika jest adresem e-mail, a podany adres e-mail jest inny smile.gif no ale to raczej mało realny przypadek.

Używam czegoś takiego:
  1. if (isset($_POST['email'], $_POST['p'])) {
  2. $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
  3. $password = $_POST['p']; // The hashed password.
  4.  
  5. if (login($email, $password, $mysqli) == true) {
  6. // Login success
  7. header("Location: ../panelphp");
  8. exit();
  9. } else {
  10. // Login failed
  11. header('Location: ../index.php?error=1');
  12. exit();
  13. }

Username jest w $_SESSION['username'] dalej nie mam pojęcia jak wykonać logowanie z username or email. Wszędzie radzą użyć w WHERE tego 'OR' niestety nie działa w moim przypadku.
Pyton_000
Pokaż zapytanie którym pobierasz dane oraz jak je odpalasz (cała otoczka zapytania)
MESSIAH :)
  1. function login($email, $password, $mysqli) {
  2. // Using prepared statements means that SQL injection is not possible.
  3. if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
  4. FROM membes
  5. WHERE email = ? LIMIT 1")) {
  6. $stmt->bind_param('s', $email); // Bind "$email" to parameter.
  7. $stmt->execute(); // Execute the prepared query.
  8. $stmt->store_result();
  9.  
  10. // get variables from result.
  11. $stmt->bind_result($user_id, $username, $db_password, $salt);
  12. $stmt->fetch();
  13. dalszy kod zawiera $password }
Pyton_000
Dodajesz do WHERE waruneek i kolejny bind_param i tyle

A no i oczywiście do funkcji musisz przekazać username
MESSIAH :)
Dodałem tylko opcje:
  1. if(strpos($email,'@') !== FALSE)

który zwraca wyniki i przekazuje dalej
com
Cytat(MESSIAH :) @ 12.01.2015, 21:41:01 ) *
Dodałem tylko opcje:
  1. if(strpos($email,'@') !== FALSE)

który zwraca wyniki i przekazuje dalej


I dało Ci to oczekiwany rezultat czy jak bo ta odp nic nie mówi, ale widzę Ty o jednym a reszta o innym, chodzi o warunek w zapytaniu a nie w php
zidek
To ja tylko dopowiem, że podając warunek "WHERE email = '{$login}'" zakładałem, że pojawi się po nim jakieś "AND ..."

Tak jak powiedział sowiq - stała sól to brak soli, ale można skorzystać np. z jakiegoś generatora soli na podstawie loginu, doklejać fragmentu loginu do hasła i potem hashować. W ten sposób na pewno żadne hasła w bazie nie będą powtarzane. No i unikamy wtedy pobierania hasła z bazy, jest ono stosowane tylko w formie hashowanej jako warunek.

Rozbicie całego procesu na dwa zapytania też nie powinno gwałtownie obciążyć serwera. W pierwszym zapytaniu pobieramy id i sól (na podstawie loginu), jeśli mamy 0 wyników możemy zwrócić odpowiedni błąd o braku użytkownika. Pobraną sól wykorzystujemy do hashowania i w drugim zapytaniu porównujemy z ciągiem zapisanym w kolumnie "password" I oczywiście także zwracamy odpowiedni błąd przy zerowej liczbie wyników.

Mniej więcej o takie rozwiązanie mi chodziło. Zresztą... co programista to inny pomysł. I dobrze.
MESSIAH :)
Cytat(com @ 12.01.2015, 21:49:44 ) *
I dało Ci to oczekiwany rezultat czy jak bo ta odp nic nie mówi, ale widzę Ty o jednym a reszta o innym, chodzi o warunek w zapytaniu a nie w php

Tak dało oczekiwany efekt. strpos przeszukuje wartość przesłaną przez $_POST i szuka w niej @ jeśli znajdzie to traktuje to jako email jeśli nie to jako username. Wiem że oni piszą o hasłach. TAK MAM HASHOWANE HASŁO + SÓL.
com
ok to dobrze smile.gif
zidek taka sol to nie sol smile.gif dlaczego, bo pierwsze co się zrobi to właśnie to sprawdzi smile.gif a nadmierna kombinacja na bazie tylko niepotrzebnie ją obciąży smile.gif
Pyton_000
A ja dalej nie rozumie tej całej kombinacji i magii...

Tworzysz tabele gdzie username i email są inikalnymi kolumnami.
Robisz panel logowania "Wpisz nazwę użytkownika lub email"
Wstawiasz to w zapytanie:
  1. SELECT username, email, password FROM users WHERE username = 'userKowalski' OR email = 'userKowalski';

Potem sprawdzasz czy zakodowane hasło zgadza się z tym w bazie i koniec. Po co jakieś sprawdzanie czy jest @.
Równie dobrze można sprawdzać czy w tym polu jest literka A - jak jest to Kobieta haha.gif
MESSIAH :)
Niestety juz próbowałem z opcją OR i nie działało. Ty masz zdefioniowany username a ja nie. U mnie email =? bo uzywam $stmt gdzie musisz przekazać ze zmiennej wartość która zostałą wysłana POSTem
phpion
Jeśli chodzi o dynamiczne podstawianie kolumny to miałem na myśli coś takiego:
  1. $stmt = $mysqli->prepare("SELECT id, username, password, salt FROM membes WHERE ".(filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE ? 'email' : 'username')." = ? LIMIT 1");
Pyton_000
sciana.gif
Chcesz powiedzieć że nie masz w bazie pola username?
Do zapytania masz podstawić to co masz z POST czyli I do username I do email MUSI iść ta sama wartość....
MESSIAH :)
Ja mam tak:
  1. $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);


Tak mam usenrame i email w bazie danych. W moim skrypcie korzystam z Anty Brute Force i anty SQL Injection
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.