Cum restricționezi accesul la wp-admin pentru anumite roluri de utilizator?

24 sept. 2012, 12:59:59
Vizualizări: 41.9K
Voturi: 11

Am încercat să folosesc plugin-ul Front End Users, dar acesta intră în conflict cu alte componente și blochează accesul la unele pagini din frontend. Așa că am nevoie să configurez manual astfel încât oricine nu face parte din două nume de utilizator specifice (sau roluri) să nu poată accesa wp-admin.

0
Toate răspunsurile la întrebare 6
17
19

Plugin

În esență, este doar o verificare a capabilității utilizatorului, urmată de o redirecționare într-un apel exit. Apoi redirecționează către site-ul de pe care a venit cererea.

<?php
! defined( 'ABSPATH' ) AND exit;
/* Plugin Name: (#66093) »kaiser« Interzice accesul la interfața administrativă pentru anumite roluri */


function wpse66093_no_admin_access()
{
    // Nu rula dacă utilizatorul este autentificat și încearcă să se deconecteze
    // Acest lucru ar putea avea nevoie de una sau două verificări suplimentare.
    // Mai ales dacă ai reguli și rute personalizate pentru autentificare/deconectare/resetare parolă/etc.
    if ( 
        ! is_admin()
        || (
            is_user_logged_in()
            && isset( $GLOBALS['pagenow'] ) AND 'wp-login.php' === $GLOBALS['pagenow']
        )
    ) {
        return;
    }

    $redirect = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : home_url( '/' );
    if ( 
        current_user_can( 'CAPABILITY_NAME_HERE' )
        OR current_user_can( 'CAPABILITY_NAME_HERE' )
    )
        exit( wp_redirect( $redirect ) );
}
add_action( 'admin_init', 'wpse66093_no_admin_access', 100 );

Ține minte că acest lucru ar trebui să funcționeze doar cu setările implicite (vezi comentariile din cod). Logica personalizată de autentificare, deconectare, înregistrare sau resetare parolă ar putea strica acest lucru.

Roluri vs. Capabilități: Deoarece numele rolurilor se pot schimba și deoarece rolurile sunt doar grupuri de capabilități, cel mai bine este să verifici o capabilitate, nu un nume de rol. Poți găsi o listă cu roluri și capabilități încorporate aici. Doar caută care este cea mai restrictivă accesare și caută o capabilitate corespunzătoare. Apoi atribuie-o mai sus. Astfel e mai ușor de întreținut, în cazul în care un nume de rol se schimbă. Da, poți folosi și un nume de rol, care va funcționa în WordPress, dar este un concept care poate aduce un bug greu de identificat atunci când un nume de rol se schimbă.

Notă: Nu gândi rolurile într-o manieră ierarhică. Gândește-te la contabilul al cărui adresă de email o introduci într-un backend SaaS pentru a primi factura. Majoritatea dezvoltatorilor nu vor avea acces la detaliile de facturare, la fel cum nici contabilul nu va avea acces la setările de deploy sau la credentialele de securitate. Ei au roluri denumite diferit, cu capabilități la fel de "înalte", dar pentru părți complet diferite. Ține minte acest exemplu când scrii verificări de capabilități sau adaugi capabilități personalizate într-un sistem.

24 sept. 2012 14:42:31
Comentarii

Deci pun asta în partea de sus a fișierului meu functions.php?

Claire Claire
24 sept. 2012 15:54:05

Fie undeva în functions.php, fie în folderul tău de plugin sau mu-plugins. Deoarece acesta nu este ceva legat de afișare, aparține după părerea mea unui plugin, de asta și antetul de plugin. Acest lucru are avantajul că această funcționalitate nu se pierde când schimbi tema. Doar modifică numele rolurilor de utilizator, încarcă-l și gata.

kaiser kaiser
24 sept. 2012 15:59:31

Nu funcționează. Am schimbat numele rolurilor de utilizator în cele două roluri care pot accesa. Apoi am schimbat-o într-o capabilitate, de exemplu Add users și încă pot accesa backend-ul cu alt rol de utilizator

Claire Claire
24 sept. 2012 18:28:36

@Nicola Există o diferență enormă între o etichetă în interfața utilizator (de exemplu: "Adaugă utilizatori") și un adevărat Rol sau Capabilitate - în cazul tău add_users.

kaiser kaiser
24 sept. 2012 20:07:56

ok mulțumesc, am încercat codul de mai sus cu add_users în loc și tot nu funcționează...dacă mă autentific ca un utilizator fără acea capabilitate, pot naviga în wp-admin

Claire Claire
26 sept. 2012 14:44:14

@Nicola Ai verificat linkul despre Roluri și Capabilități ↑ din comentariul de mai sus? Te rog să te asiguri că utilizatorul chiar nu are acea capabilitate.

kaiser kaiser
26 sept. 2012 14:48:22

Hei, cu siguranță nu au această capacitate. Tocmai am introdus codul în fișierul meu functions.php, deoarece nu eram sigur cum să-l adaug ca un plugin pe care WordPress l-ar recunoaște. De asemenea, am avut o eroare unde $_SERVER['HTTP_REFERER'] era un index nedefinit, așa că am adăugat o regulă if isset înainte de el.

Claire Claire
26 sept. 2012 15:13:39

Ah, bine. Acum știm unde este problema: am actualizat răspunsul, dar ar trebui să adaug asta ca un plugin. Este unul, va fi recunoscut. Doar că nu am adăugat antetul complet (ceea ce nu este necesar). Poți să-l rulezi și ca mu-plugin (citește pe codex despre asta). Cel mai bine este să-l păstrezi ca plugin, astfel încât să nu se piardă la schimbarea temei.

kaiser kaiser
26 sept. 2012 15:28:01

Ok, poți să-l editezi pentru a face if isset, deoarece declanșează din nou acel index nedefinit 'HTTP_REFERER', și nu sunt sigur de logica ta pentru a ști dacă l-am editat corect.

Claire Claire
26 sept. 2012 16:17:23

hei, e super, am făcut să redirecționeze către pagina principală a site-ului. Funcționează acum, mulțumesc!

Claire Claire
26 sept. 2012 16:20:13

Salut din nou, am o altă cerință. Am un plugin care permite unui utilizator să-și actualizeze fotografia din partea frontală. Acest plugin trebuie să facă unele operațiuni ajax în backend pentru a face asta.

Deci, în codul de mai sus, cred că trebuie să fac o verificare pentru a vedea dacă suntem pe acea pagină. Totuși, deoarece suntem în directorul pluginului, nu știe pagina curentă prin funcțiile WordPress, așa că am folosit $page = array_shift( explode( '?', $_SERVER['REQUEST_URI'] ) );, și apoi am încercat să modific codul de mai sus să spună if ( current_user_can( 'add_users' ) || $page=="/your-profile/"){, dar nu funcționează.

Claire Claire
8 oct. 2012 12:05:20

@Nicola Te rog să aduci întotdeauna astfel de informații la întrebarea inițială ca editare, nu într-un comentariu aici. În al doilea rând, te rog să pui o nouă întrebare când subiectul tău s-a schimbat sau extins. Mulțumesc.

kaiser kaiser
8 oct. 2012 12:07:37

Este în regulă, am rezolvat apelând un die($page) și am realizat că plugin-ul era apelat doar când dădeam click pe editare profil, moment în care $page="/wp-admin/admin-ajax.php". Am rezolvat acum.

Claire Claire
8 oct. 2012 12:08:24

ok, îmi pare rău pentru asta

Claire Claire
8 oct. 2012 12:08:57

WordPress va începe probabil să declanșeze o eroare _doing_it_wrong() când verifică un nume de rol ca și capabilitate în current_user_can(). Vezi 38653

Nathan Johnson Nathan Johnson
16 apr. 2017 19:43:10

Frumos, totuși utilizatorii nu se pot deconecta din cauza acestei acțiuni.

berend berend
29 iun. 2017 13:00:03

Nu uitați să verificați defined('DOING_AJAX') dacă aveți apeluri AJAX în frontend, altfel vor fi blocate!

Ste_95 Ste_95
19 aug. 2020 09:46:18
Arată celelalte 12 comentarii
0

Tocmai am revizuit acel răspuns deoarece nu a fost actualizat de mult timp. Anul este 2021.

Răspunsul acceptat verifică dacă pagina curentă este o pagină wp-login.php SAU o pagină de administrare ÎN TIMP CE utilizează un hook admin_init, ceea ce nu are sens.

admin_init se declanșează când un ecran sau script de administrare este inițializat. NU rulează doar pe ecranele de administrare vizibile utilizatorilor. Rulează și pe admin-ajax.php și admin-post.php.

În niciun caz nu se va declanșa pe wp-login.php deoarece acesta NU este un ecran de administrare. Totuși, se va declanșa la o cerere ajax, de aceea acest caz ar trebui gestionat. wp_doing_ajax() determină dacă cererea curentă este o cerere Ajax WordPress.

În exemplul următor folosesc capacitatea delete_posts pentru a permite accesul la backend-ul WordPress pentru admin, editor și author. Consultați Tabelul Capacități vs. Roluri pentru o abordare mai restrictivă.

Ca o reamintire, iată rolurile implicite în WordPress (Rezumatul Rolurilor):

super admin admin editor author contributor subscriber.

Într-o instalare WordPress cu un singur site, Administratorii sunt, de fapt, Super Admini.

Am ales să folosesc wp_die() în loc să redirecționez utilizatorii orbește. wp_die() oferă un fel de onboarding pentru utilizatori deoarece oprește execuția WordPress și afișează o pagină HTML cu un mesaj de eroare. Aceeași abordare ar putea fi făcută prin redirecționarea utilizatorilor către o pagină 404. Orice ce explică situația este mai bun decât o redirecționare orbească către pagina principală.

add_action( 'admin_init', 'restrict_wpadmin_access' );
if ( ! function_exists( 'restrict_wpadmin_access' ) ) {
    function restrict_wpadmin_access() {
        if ( wp_doing_ajax() || current_user_can( 'delete_posts' ) ) {
            return;
        } else {
            header( 'Refresh: 2; ' . esc_url( home_url() ) );
            $args = array(
                'back_link' => true,
            );
            wp_die( 'Acces restricționat.', 'Eroare', $args );
        };
    };
};

Pentru a preveni redirecționarea implicită către wp-admin.php după autentificare, folosesc filtrul hook login_redirect care filtrează URL-ul de redirecționare la autentificare. Îi redirecționez către propria pagină de profil folosind get_author_posts_url(), dar puteți redirecționa ușor către orice pagină doriți. De asemenea, puteți redirecționa condiționat în funcție de rolul utilizatorului (de ex: admin către pagina de administrare, restul către profil), totul este explicat în secțiunea de exemplu din pagina CODEX.

add_filter( 'login_redirect', 'redirect_user_to_profile_on_login', 10, 3 );
if ( ! function_exists( 'redirect_user_to_profile_on_login' ) ) {
    function redirect_user_to_profile_on_login( $redirect_to, $requested_redirect_to, $user ) {
        if ( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
            $redirect_to = esc_url( get_author_posts_url( $user->ID ) );
        };
        return $redirect_to;
    };
};
25 mar. 2021 13:20:20
1

Răspunsul acceptat menționează Rolul Utilizatorului, dar de fapt utilizează funcția pentru Capabilitatea Utilizatorului.

Iată soluția pentru Rolurile Utilizatorilor:

 function wpse66094_no_admin_access() {
    $redirect = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : home_url( '/' );
    global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
    if($user_role === 'ROLUL_TAU_DE_UTILIZATOR_AICI'){
        exit( wp_redirect( $redirect ) );
    }
 }

add_action( 'admin_init', 'wpse66094_no_admin_access', 100 );
6 apr. 2015 18:17:51
Comentarii

Ar trebui să verifici capabilitățile, nu rolurile. După cum este menționat în pagina CODEX a funcției current_user_can(): "Deși verificarea în funcție de anumite roluri în locul unei capabilități este parțial acceptată, această practică este descurajată deoarece poate produce rezultate nesigure. @see https://developer.wordpress.org/reference/functions/current_user_can/#description

amarinediary amarinediary
7 ian. 2022 13:16:50
0

Bazat pe răspunsul oferit de @kaiser (mulțumesc, apropo), acesta este codul meu funcțional, în caz că cineva are nevoie de el. Acesta este plasat în fișierul functions.php.

Condiția utilizată este dacă utilizatorul nu poate manage_options sau edit_posts.

function wpse66093_no_admin_access() {
    $redirect = home_url( '/' );
    if ( ! ( current_user_can( 'manage_options' ) || current_user_can( 'edit_posts' ) ) )
        exit( wp_redirect( $redirect ) );
}
add_action( 'admin_init', 'wpse66093_no_admin_access', 100 );
4 sept. 2015 12:11:25
0

Cu răspunsul lui @kaiser am aflat că va trebui să folosești hook-ul admin_menu în loc de admin_init, deoarece acesta se declanșează înainte de verificarea !user_can_access_admin_page() din wp-admin/includes/menu.php. Altfel, dacă utilizatorul nu are acces 'read' la panoul de control, va primi doar pagina 'Nu aveți permisiuni suficiente pentru a accesa această pagină.' în loc să fie redirecționat.

8 apr. 2016 03:02:38
1

Dacă eliminați capabilitatea read din Rol, utilizatorul nu va mai putea accesa panoul de control. Acesta va primi următoarea eroare:

Nu aveți permisiunile necesare pentru a accesa această pagină de administrare.

Motiv: Utilizatorul curent nu posedă capabilitatea "read" care este necesară pentru a accesa elementul de meniu "Panou de control".

Referință: https://codex.wordpress.org/Roles_and_Capabilities#read

25 feb. 2019 19:15:47
Comentarii

poate fi util de menționat că un utilizator fără capabilități poate totuși să se autentifice cu succes și bara de administrare este afișată.

kubi kubi
20 mai 2020 16:29:19