Interdire l’authentification d’un utilisateur (ou plusieurs)
Imaginez cette situation : votre site est protégé par un formulaire de connexion personnalisé, et vous souhaitez que vos clients puissent accéder à la partie front-end, mais pas au BackOffice.
L’objectif ici est de bloquer l’accès lors de l’authentification classique de WordPress, tout en validant correctement les utilisateurs.
Valider un utilisateur avec un formulaire personnalisé
La première étape consiste à comprendre comment authentifier un utilisateur via notre formulaire personnalisé. La fonction wp_authenticate() est la clé, car elle permet de valider le couple identifiant/mot de passe.
$login = $_POST['login']; $password = $_POST['password']; $user_data = wp_authenticate( $login, $password ); if ( ! is_wp_error( $user_data ) ) { // votre logique pour rester connecter ensuite (cookie ?) }
La fonction wp_authenticate() est d’une grande simplicité car elle se charge de vérifier la validité du couple identifiant/mot de passe. (la doc ici)
Vous voulez en savoir plus ?
Lorsque nous examinons le code source, nous pouvons constater qu’il n’y a pas beaucoup de détails, mais une chose intéressante attire notre attention : un filtre est créé.
$user = apply_filters( 'authenticate', null, $username, $password );
Si nous consultons la documentation pour mieux comprendre son fonctionnement, nous découvrons que ce filtre est lié à trois hooks.
add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 );
En résumé, ces hooks vont contrôler le couple d’identifiant et renvoyer l’utilisateur si tout est conforme.
L’avantage de wp_authenticate() réside dans sa simplicité : il se contente de valider ou de refuser l’utilisateur, sans créer de cookie de connexion comme c’est le cas lorsque l’utilisateur se connecte via les formulaires classiques de WordPress.
À ce stade, nous savons comment valider les identifiants de nos utilisateurs WordPress.
Bloquer l’utilisateur sur les formulaires de connexion natifs
Quel hook utiliser ? Celui-ci est parfaitement adapté : wp_authenticate_user, car il permet de vérifier si l’utilisateur et son mot de passe correspondent.
La vérification du mot de passe a lieu après le hook, mais nous n’avons pas besoin de cette vérification, car nous avons déjà obtenu la confirmation d’une tentative d’authentification grâce à l’identifiant (ou email). Comme nous souhaitons arrêter le processus à ce stade, il est inutile de tester le mot de passe => la doc ici
add_filter( 'wp_authenticate_user', 'samy_wp_authenticate_user', 1 ); function samy_wp_authenticate_user( $user ) { if ( is_wp_error( $user ) ) { return $user; } if ( '[email protected]' == $user->user_email && ( ! isset( $_REQUEST['custom_form'] ) || '' === $_REQUEST['custom_form'] ) ) { return new \WP_Error( 'type_error', __( '<strong>ERROR</strong>: Connection failed.', 'TEXTDOMAIN' ) ); } return $user; }
Explications
Lignes 8 à 10 : Dans ces lignes, nous effectuons deux contrôles cruciaux. Tout d’abord, nous vérifions que l’adresse e-mail correspond bien au compte que nous souhaitons bloquer. À noter qu’il est tout à fait possible de modifier cette vérification en utilisant un tableau d’adresses e-mail, ce qui nous permettrait de bloquer plusieurs comptes en même temps.
Ensuite, nous effectuons un autre contrôle essentiel. Nous vérifions que nous ne sommes pas sur le formulaire personnalisé. Il est important de rappeler que, lors de l’utilisation du formulaire personnalisé, nous utilisons la fonction wp_authenticate() qui va examiner le couple d’identifiant/mot de passe pour valider ou refuser l’accès. Par conséquent, il est impératif de bien définir le contexte pour garantir le bon fonctionnement du processus de blocage.
Ces contrôles sont fondamentaux pour s’assurer que seuls les comptes spécifiques que nous souhaitons bloquer seront effectivement restreints.
Est-ce suffisant ?
On pourrait s’arrêter là mais on veut faire les choses comme elle doit être faite.
2 points sont encore à contrôler :
- si l’utilisateur arrive par une manière détourner de se connecter, comme s’assurer de le bloquer ?
add_action( 'init', 'samy_control_login' ); function samy_control_login() { if ( is_user_logged_in() ) { $current_user = wp_get_current_user(); if ( '[email protected]' === $current_user->user_email ) { wp_logout(); } } }
On contrôle si l’utilisateur est connecté et s’il correspond à celui qu’on souhaite bloquer => on le déconnecte (ici encore la logique est a adapter en fonction du contexte : un ou plusieurs utilisateurs à bloquer, par rôle, etc.)
- on peut également contrôler les droits/rôles de ou des utilisateurs afin de s’assurer de contrôler les chose d’un bout à l’autre.
add_action( 'init', 'samy_remove_all_caps_specific' ); function samy_remove_all_caps_specific() { $specific_user = get_user_by( 'email', '[email protected]' ); if ( $specific_user instanceof \WP_User ) { $specific_user->remove_all_caps(); } }
Le principe est simple, on supprime constamment les droits de l’utilisateur (ou on force certain droits/rôles tout dépend du contexte/besoin). Cette partie permet de contrôler correctement notre utilisateur et ainsi toujours intervenir au besoin. Par exemple si dans l’administration des utilisateurs, on change le rôle de ce dernier, notre code remodifiera le profil pour remettre comme on le souhaite.