Mostrare l'endpoint di un custom post type nell'API REST solo se l'utente ha la capability
Ho creato un custom post type per WordPress che dovrebbe essere accessibile solo agli utenti con una capability personalizzata read_cpt
. Nei template e in pre_get_posts
posso eseguire controlli per includere o escludere il CPT usando current_user_can()
.
Non voglio che il CPT, né tantomeno l'endpoint, venga mostrato nell'API REST, per mantenerlo segreto, a meno che l'utente non abbia la capability personalizzata.
L'unico modo che ho trovato per nascondere gli endpoint nell'API è eseguire questo codice.
Registrazione del post type per il "classico" WordPress:
function add_post_type() {
$args = array(
[...]
'public' => false,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'show_in_rest' => false,
);
register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type', 0 );
e aggiungerlo separatamente all'API REST:
add_action( 'init', 'cpt_rest_support', 25 );
function cpt_rest_support() {
global $wp_post_types;
if ( current_user_can( 'read_addresses' ) ) {
//assicurati di impostare questo con il nome del tuo post type!
$post_type_name = 'address';
if( isset( $wp_post_types[ 'cpt' ] ) ) {
$wp_post_types[ 'cpt' ]->show_in_rest = true;
}
}
}
Creando una classe personalizzata WP_REST_Posts_Controller
non ho trovato un modo per nascondere l'endpoint modificando uno dei *_permissions_check
Esiste qualcosa come un argomento "show_in_rest_permition_check" per register_post_type()
oppure il metodo descritto è l'unico disponibile?

L'API REST non ha parametri o opzioni per risolvere questo problema, a mio avviso. Tuttavia, dovresti registrarla solo se gli utenti hanno le capacità necessarie nel loro ruolo, come nell'esempio seguente.
add_action( 'rest_api_init', function() {
// Esci se l'utente loggato non ha sufficienti permessi.
if ( ! current_user_can( 'edit_posts' ) ) {
return;
}
// Registra i Meta Dati.
register_meta( 'post', 'foo', array(
'show_in_rest' => true,
));
});
Questo fa sì che i dati personalizzati vengano inclusi nell'API REST solo se l'utente ha i diritti e le capacità necessarie nel suo ruolo. Il mio register_meta()
è solo un esempio, e dovrebbe funzionare anche con il tuo parametro aggiuntivo per register_post_type
, come $wp_post_types[ 'cpt' ]->show_in_rest = true;
.

Vecchia domanda ma questa soluzione ha funzionato per me seguendo i requisiti di @Drivingralle. Puoi usare current_user_can()
come interruttore booleano per modificare il comportamento del parametro show_in_rest
:
function add_post_type() {
$show_in_rest = current_user_can( 'read_cpt' ); //questo restituirà vero o falso
$args = array(
[...]
'public' => false,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'show_in_rest' => $show_in_rest, //interruttore booleano da current_user_can()
);
register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type' );
In questo modo il custom post type viene mostrato nell'API REST solo per gli utenti con le capacità richieste.

Non fare affidamento solo sul nasconderlo.
Invece, restituisci un errore nell'handler:
if (!current_user_can('read_addresses')) {
return new WP_REST_Response('accesso negato', 403);
}
Per nasconderlo anche, filtra il contenuto degli hook rest_index
e rest_namespace_index
.

Utilizza la funzione register_rest_route().
if( current_user_can( 'read_addresses' ) ) {
register_rest_route( 'namespace/v1', 'cpt', array(
'methods' => array( 'GET' ),
'callback' => 'callback_function',
'permission_callback' => 'permission_callback_function'
) );
}
La tua callback_function
gestirà la richiesta e restituirà la risposta. La permissions_callback_function
controllerà i permessi dell'utente e restituirà un errore se l'utente non ha le capacità specificate. In questo caso il callback dei permessi probabilmente non è necessario, ma non fa male averlo comunque per sicurezza.
