Wsparcie » Wtyczki » Użycie hooka wp_authenticate nie pozwala się zalogować

  • carbon9610

    (@carbon9610)


    Witajcie.

    Tworzę plugin, którego zadaniem jest sprawdzenie, czy uwierzytelnienie w systemie WordPress i oprogramowaniu forumowym się zgadza, a jeśli tak, to umożliwia zalogowanie w WordPressie (coś na zasadzie mostka). Więc dodałem hooka add_action('wp_authenticate' , 'xyz_login');, a następnie stworzyłem funkcję, która weryfikuje cały proces. Wszystko zostało sprawdzone kawałek po kawałku i w zasadzie działało do momentu przetestowania na serwerze. Jeżeli użytkownik poda dane, które nie pasują ani w WP, ani na forum, oznacza to, że prawdopodobnie nie ma konta i zostaje przekierowany do formularza rejestracyjnego. Takie jest założenie pluginu. Jednak problem leży w trochę innym miejscu. Po wejściu w link /wp-login.php automatycznie przenosi od razu do formularza rejestracyjnego, zamiast wyświetlić formularz logowania i dopiero później zweryfikować logowanie. Wygląda to tak, że plugin chce weryfikować logowanie już przy samym przejściu do strony logowania. Prawdopodobnie dlatego, gdyż POST już z jakiegoś względu wysyła POSTEM zmienne o wartości null.

    Pytania mam zasadniczo dwa:
    1. Dlaczego tak się dzieje? (zastanawiam się, czy to nie wina aktualizacji, gdyż kilka miesięcy temu testy przebiegły bezproblemowo)

    2. Na jakiej zasadzie działa wp_authenticate? (manual już znam na pamięć. Nie odsyłajcie mnie do niego 🙂 ). Wyobrażam to sobie tak, że wchodzę w formularz (login_form), wypisuję dane, klikam „ZALOGUJ” i WordPress wywołuje wp_signon (a pierwszym etapem autoryzacji jest właśnie wp_authenticate). Jeżeli tak jest, to dlaczego wtyczka pobiera parametr z funkcji przy przechodzeniu do formularza, a nie po jego wysłaniu?

    3. Może źle do tego podchodzę i używam złego hooka?

    4. Może błąd leży po mojej stronie i powinienem na wszelki wypadek sprawdzać zawczasu, czy formularz nie jest pusty? Tylko w takim wypadku – co dalej? Wiedząc, że wp_authenticate działa po wysłaniu formularza, to nie wiem jak sprawdzenie tego ma mi pomóc przy włączaniu formularza (gdyż formularz wtedy będzie pusty i tak).

    Jeżeli coś jest niejasne, wytłumaczę. Jeśli jest potrzebna jakaś część kodu, pokażę 😉 Póki co interesuje mnie głównie merytoryka.

    Pozdrawiam 🙂

Viewing 6 replies - 1 through 6 (of 6 total)
  • Paweł

    (@mrpauloen)

    Merytoryka swoją drogą, ale na pewno kawałek kodu, który używasz byłby pomocny.

    Thread Starter carbon9610

    (@carbon9610)

    Proszę 😉 Wydaje mi się, że to wszystko, co może się przydać. Tam, gdzie jest komentarz z warunkami, to wiadomo, o co chodzi. Jest tam po prostu sprawdzane uwierzytelnianie MyBB i WP oraz weryfikowane względem porównania tych danych. Ilość nawiasów klamrowych na końcu jest efektem warunków, więc na ich nadmiar proszę nie patrzeć 🙂

    add_action('wp_authenticate' , 'mybb_login');
    function mybb_login($username) {
    	global $wpdb;
    	$rooturl = getenv('HTTP_HOST');
    	
    	$prefix = $wpdb->prefix;  
    	$bridge_tablename = $prefix."bridge";
    	
    	//Get MyBB database information
    	$getenabled = $wpdb->get_row("SELECT * FROM {$bridge_tablename}");
    	$enabledstatus = $getenabled->enabled;	
    	$mybb_dbaddress = $getenabled->address;	
    	$mybb_dbusername = $getenabled->dbusername;	
    	$mybb_dbuserpwd = $getenabled->dbuserpwd;	
    	$mybb_dbname = $getenabled->dbname;
    	$mybb_tableprefix = $getenabled->tableprefix;
    	$mybb_forumurl = $getenabled->forumurl;
    	
    	
    	// Break function, if plugin hasn't permission to execute.
    	if($enabledstatus == 0) {
    		return;
    	}
    	
    	// Connect with MyBB database
    	$mydb_connecti = new mysqli($mybb_dbaddress, $mybb_dbusername, $mybb_dbuserpwd, $mybb_dbname);
    
    	if($mydb_connecti->connect_error) {
    		die('Connect Error (' . $mydb_connecti->connect_errno . ') ' . $mydb_connecti->connect_error);
    	}
    	
    	else {
    		$mydb_connecti->set_charset("utf8");
    
    		// Warunki
    		
    				// Sam koniec kodu, który stanowi problem
    				else {
    					header("Location: $mybb_forumurl/member.php?action=register");
    					return;
    				}
    			}
    			
    			$mydb_connecti->close;
    		}
    	}
    Paweł

    (@mrpauloen)

    Jaką wartość dostaje zmienna:
    $getenabled ?
    Czy możesz ją wydrukować?
    W zapytaniu chcesz pobrać wszystko z tabeli bridge, ale używasz do tego get_var.
    To chyba się kłóci jedno z drugim i wydaje mi się, że powinieneś użyć funkcji get_row.

    Edit: A przepraszam. get_row. Nie wiem skąd mi się wzięło get_var.

    Z kodu wynika, że masz jedną bazę danych dal WP I MyBB. Tak?

    I to chyba nie jest pełny kod?

    • Ta odpowiedź została zmodyfikowana 7 years temu przez Paweł.
    • Odpowiedź została zmodyfikowana 7 years temu przez Paweł. Powód: poprawiona pomyłka
    Thread Starter carbon9610

    (@carbon9610)

    $getenabled w tabeli jest zadeklarowany jako tinyint o długości znaków 1, jednak w ostatecznym rozrachunku zawsze dostaje wartość zero-jedynkową. [EDIT:] Tak, jest drukowana.

    Tak, są dwie bazy.

    Pewnie, że to nie jest cały kod. Są olane wszystkie warunki poza tym ostatnim. Jeżeli jest to potrzebne, mogę pokazać (choć jeśli byłaby możliwość, to wolałbym, aby odbyło to się na jakimś privie 🙂 )

    • Ta odpowiedź została zmodyfikowana 7 years temu przez carbon9610.
    Paweł

    (@mrpauloen)

    Tylko coś mi tu nie pasuje w tym skrypcie. Oczywiście rozumiem, że nadal chodzi o sprawdzenie czy dany użytkownik znajduje się w bazie danych. Tylko nigdzie tego tu w tym kodzie nie widać.

    Gdybym miał sprawdzić podczas logowania czy dana osoba jest zarejestrowana, najpierw pobrał bym jego email z formularza:

    $email = $_POST['email'];

    gdyż email jest jak główny klucz w bazie – jest unikalny. Dopiero potem sprawdził bym czy użytkownik o takim adresie znajduje się w bazie. Należało by więc zapytać:

    $database->query('SELECT * FROM users WHERE email = :email');
    $database->bind(':email', $email);
    $database->execute();
    $user_meta = $database->fetchObject();

    Oczywiście wykorzystuję tu inny kod pobrany ze swojego skryptu opartego o klasę PDO.

    Ale analogia jest ta sama.

    Jeżeli użytkownik nieistnieje, warunek daje false.

    if ( !$user_meta ){
    
    // wykonaj kod
    } else {
    
    // wykonaj kod
    }

    Jeżeli istnieje, wtedy mamy i jego imię i hasło i co tylko chcemy, gdyż użyliśmy gwiazdki. Ale w twoim przypadku nic takiego się nie stanie.

    Twoje zapytanie pobiera wszystko z tabeli. W technicznym sensie jest to nieekonomiczne.

    Chyba, że ja czegoś tu nie rozumiem i ta tabela ma całkiem inny charakter i dotyczy czegoś innego. Próbuje się dopatrzeć… Hmm no tak. tak chyba jest. Ta tabela nie zawiera informacji o użytkowniku?

    Być może, cały kod byłby pomocny.

    $getenabled w tabeli jest zadeklarowany jako tinyint o długości znaków 1,

    Pytałem o wartość zmiennej gdyż chciałem widzieć co się w niej znajduje. Co otrzymujemy po postawieniu zapytania do bazy.

    Thread Starter carbon9610

    (@carbon9610)

    Tylko coś mi tu nie pasuje w tym skrypcie. Oczywiście rozumiem, że nadal chodzi o sprawdzenie czy dany użytkownik znajduje się w bazie danych. Tylko nigdzie tego tu w tym kodzie nie widać.

    To pierwszy warunek, który sprawdzam 😉

    if(username_exists($username)) {
    				// Got user's pwd	
    				$userwp_pwd = $_POST['pwd'];
    
    				// Get user's hash in WordPress
    				$userwp = get_user_by('login', $username);
    				$userwp_pass = $userwp->user_pass;
    				$userwp_id = $userwp->ID;
    				
    				// Get user's hash in MyBB
    				$ts_user = "SELECT <code>password</code>, <code>salt</code> FROM {$mybb_tableprefix}users WHERE <code>username</code> = ?";
    
    [...]

    W ogóle krążymy w koło nie tego tematu, co trzeba. Skrypt logowania działa jak trzeba. Ale po wysłaniu na serwer wp_authenticate wykonuje się w złym momencie. Nie po kliknięciu „Zaloguj”, a przy przejściu do formularza. I muszę dojść do tego, dlaczego tak się dzieje.

    Twoje zapytanie pobiera wszystko z tabeli. W technicznym sensie jest to nieekonomiczne.

    Moje zapytanie pobiera TYLKO I WYŁĄCZNIE dane potrzebne do połączenia z bazą. A jako, że tak jest tabela skonstruowana, że znajdują się w niej tylko te dane (+ prefiks tabeli, który też będzie potrzebny), to pobiera wszystko 😉 W żadnym miejscu kodu nie ma pobierania nadmiarowych danych.

Viewing 6 replies - 1 through 6 (of 6 total)
  • Temat ‘Użycie hooka wp_authenticate nie pozwala się zalogować’ jest zamknięty na nowe odpowiedzi.