Come verificare username/password senza autenticare l'utente

9 ago 2012, 18:39:28
Visualizzazioni: 25.7K
Voti: 6

Sto sviluppando un plugin che crea un endpoint API per validare le coppie username/password.

Attualmente sto usando wp_signon() per verificare se la combinazione username/password funziona. Questo funziona bene quando le credenziali falliscono perché restituisce un oggetto di errore. Ma quando le credenziali sono corrette, autentica automaticamente quell'utente, quindi il mio endpoint restituisce un'intera pagina.

Il codex attualmente non menziona nemmeno il fatto che effettua automaticamente il login dell'utente. Inoltre non sembra accettare un parametro per sopprimere questa funzionalità. Per i miei scopi basterebbe un semplice booleano.

AGGIORNAMENTO: Ho dovuto scegliere una singola risposta, ma c'erano molte informazioni utili in diverse altre risposte che cercherò di riassumere brevemente qui...

  1. ESISTE una funzione che fa esattamente quello che stavo cercando di fare: wp_authenticate($username, $password) TUTTAVIA, ha un inconveniente. Imposterà automaticamente i cookie di login che possono creare problemi in una situazione come la mia. Quindi fate attenzione. Questa funzione non è attualmente nel codex.

  2. La scelta migliore per quello che sto facendo è wp_authenticate_username_password($user, $username, $password) perché NON imposta i cookie di login. Questa funzione è più documentata, ma il dettaglio VERAMENTE importante che non era nel codex è che puoi passare NULL come primo parametro. Questo significa che puoi effettivamente usarla per fare esattamente come wp_authenticate() senza preoccuparti che i cookie vengano compromessi. Leggi la documentazione per non farti confondere dalla risposta. Restituisce un oggetto WP_User oppure un WP_Error (non un booleano!).

4
Commenti

Il Codex è gestito dagli utenti. Basta accedere e modificare/aggiungere ciò che pensi manchi. (Vedilo come vedi Wikipedia).

kaiser kaiser
9 ago 2012 19:55:26

Nota: wp_authenticate in realtà non imposta i cookie di login, questo avviene in wp_signon. Tuttavia, wp_authenticate applicherà tutti i metodi di autenticazione collegati, quindi se un auth-cookie valido viene inviato insieme alla richiesta, può validare l'utente indipendentemente da username/password. Se vuoi solo verificare username e password, wp_authenticate_username_password è effettivamente la scelta corretta.

Otto Otto
14 ago 2012 00:52:06

hai mai rilasciato questo plugin/endpoint?

lofidevops lofidevops
25 ott 2017 01:02:20

@d3vid Questo era per un progetto privato di anni fa, quindi il codice dovrebbe essere aggiornato per essere compatibile con l'attuale WP. Ma se è qualcosa che ti interessa, inviami un'email.

emersonthis emersonthis
25 ott 2017 01:35:08
Tutte le risposte alla domanda 4
4
10

C'è una funzione nei user.php dei file core chiamata wp_authenticate_username_password che sembra essere ciò che stai cercando.

Se vuoi evitare di passare l'oggetto $user (probabilmente hai solo username + password), allora passa semplicemente null come primo argomento della funzione:

$check = wp_authenticate_username_password( NULL, 'nome_utente', '#lapassword' );

Puoi poi verificare facilmente il risultato con is_wp_error( $check ).

9 ago 2012 19:15:15
Commenti

Questo non fa quello che sembra. È un errore comune (che ho fatto anche io). Però ho appena scoperto una funzione che fa esattamente quello che vogliamo! Vedi la mia risposta...

emersonthis emersonthis
9 ago 2012 19:54:24

+1 sembra essere il modo perfetto. Spero non ti dispiaccia la modifica.

kaiser kaiser
9 ago 2012 19:54:29

@kaiser "Eh". Non avevo mai realizzato che si potesse passare NULL come primo parametro. Buono a sapersi. Dai anche un'occhiata a wp_authenticate() (vedi la mia risposta). L'ho trovato dopo settimane di ricerche.

emersonthis emersonthis
9 ago 2012 20:03:58

Sicuramente il modo più efficiente.

Adam Adam
9 ago 2012 20:04:20
1

Utilizza,

e

Spiegazione

// ottieni l'utente tramite login usando lo username fornito (input del form)
$user = get_user_by('login', $username);

// assegna l'ID dell'utente basato sul nome di login
$user_id = $user->ID;

// ottieni i dati dell'utente passando la variabile $user_id a get_userdata
// che restituisce l'oggetto utente e una serie di informazioni correlate all'utente da accedere
$user_data = get_userdata($user_id);


// assegna lo username e la password a delle variabili
$user_login = $user_data->user_login;
$user_pass = $user_data->user_pass;

// verifica lo username/password rispetto ai valori inviati dall'input
if ($user_login = $username && $user_pass = $password) {

// fai qualcosa...

Note

  • $username dovrebbe validare true di default altrimenti un oggetto utente non sarebbe stato restituito se lo $username fornito non corrispondeva a uno già esistente nel database. Pertanto la validazione dipende quindi dalla variabile $password che memorizza l'input del form fornito dall'utente.

  • Potrebbe esserci un modo più efficiente per ottenere questo risultato, sia accorciando il codice esistente sia utilizzando altre funzioni dell'API.

AGGIORNAMENTO

Basandoti sul suggerimento di fdsa potresti a tua volta usare wp_authenticate_username_password in questo modo,

$auth = wp_authenticate_username_password($user, $username, $password);

if (!$auth->user_login = $username && !$auth->user_pass = $password) {

echo 'non autenticato';

} else {

echo 'autenticato';

}

Ma ancora meglio,

$auth = wp_authenticate_username_password($user, $username, $password);

if (is_wp_error($auth)) {

echo 'non autenticato';

} else {

echo 'autenticato';

}

In realtà il credito/risposta migliore dovrebbe essere dato a fdsa per il metodo più efficiente tramite una (purtroppo) funzione core di WP non documentata.

http://wpseek.com/wp_authenticate_username_password/

9 ago 2012 19:12:55
Commenti

È fantastico. Ma get_userdata restituirà la password crittografata (non quella in chiaro). Hai qualche consiglio su come aggirare questo problema?

emersonthis emersonthis
9 ago 2012 19:33:47
0

Disclaimer: Questa risposta è solo per mostrare cosa succede dietro le quinte e non vuole essere un esempio reale su come fare le cose.


Backtrace

wp_signon() chiama wp_set_auth_cookie(), che a sua volta chiama wp_generate_auth_cookie(). Il risultato verrà utilizzato all'interno di setcookie() come 2nd argomento.

(Non performante) divertimento con i filtri

alias ingannare WordPress nel modo sbagliato.

Potresti quindi intervenire nel filtro 'auth_cookie' all'interno di wp_generate_auth_cookie() e semplicemente impostarlo a null o a qualcos'altro rispetto ai valori SECURE_AUTH_COOKIE o AUTH_COOKIE. Questo ti lascerà con un cookie inutile, che non può effettuare il login.

9 ago 2012 20:15:30
6

"Ecco qui": wp_authenticate($username, $password)

Non è documentato nel codex, ma puoi cercarlo su wpseek.

Fa esattamente quello che sembra. Prende un nome utente e una password in testo semplice e restituisce un oggetto WP_User oppure un WP_Error... e NON effettua il login di nessuno.

Attenzione! Il seguente codice restituirà SEMPRE true (perché la funzione restituisce comunque un oggetto):

$auth = ( wp_authenticate($username, $password) ) ? TRUE : FALSE;

Probabilmente vorrai fare qualcosa del genere:

$test_creds = wp_authenticate($username, $pass);
$class = get_class($test_creds);
$auth = ( $class == 'WP_User' ) ? TRUE : FALSE;

Spero che questo sia utile a qualcuno.

9 ago 2012 19:59:08
Commenti

Puoi usare instanceof o is_a() per verificare WP_User. Potresti anche semplicemente usare una delle funzioni sopra citate e rimuovere il filtro su authenticate...

kaiser kaiser
9 ago 2012 20:03:17

Consiglio di usare is_wp_error($auth) che restituirà TRUE se l'autenticazione fallisce e FALSE se l'autenticazione ha successo.

Adam Adam
9 ago 2012 20:07:56

Un'altra nota: Questo non ti farà accedere, ma ti lascerà comunque il cookie impostato, poiché la funzione chiama il filtro `'authenticate`. Se opti per questa soluzione, dovresti assicurarti con certezza che tutte le callback del filtro siano rimosse. Altrimenti il cielo potrebbe caderti sulla testa :)

kaiser kaiser
9 ago 2012 20:20:21

È bene saperlo. Anche wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' ); ha lo stesso problema? Puoi approfondire leggermente sul "cielo che cade"? Cosa andrà storto?

emersonthis emersonthis
9 ago 2012 20:56:20

Nota: Invece di usare wp_authenticate dovresti effettivamente usare user_pass_ok($user_login, $user_pass) che a sua volta utilizza wp_authenticate essendo la funzione wrapper corretta che restituisce true/false. Tuttavia, come ha detto @kaiser, il cookie viene impostato tramite il filtro authenticate. La funzione wp_authenticate_username_password invece non sembra impostare il cookie.

Adam Adam
9 ago 2012 21:02:33

Secondo la documentazione, wp_authenticate() EFFETTIVAMENTE effettua il login dell'utente se le credenziali sono corrette. Stranamente per me non funziona.

Gerald Schneider Gerald Schneider
25 lug 2013 10:16:01
Mostra i restanti 1 commenti