A API REST do WP exige senha para o ponto de extremidade GET

8

Eu tenho um tipo de postagem personalizado card, que estou expondo através da API REST do WP. Existe uma maneira de exigir autenticação, com cookie ou cabeçalho de autenticação básica? Vejo um argumento no bloco do método POST para senha, mas não sei como usá-lo.

insira a descrição da imagem aqui

YarGnawh
fonte

Respostas:

9

Quando registramos uma rota de descanso register_rest_route(), podemos usar o permission_callbackparâmetro com o tipo de permissão que queremos.

Verifique, por exemplo, como WP_REST_Posts_Controller::register_routes()e WP_REST_Users_Controller::register_routes()implemente o retorno de chamada da permissão.

O argumento de senha a que você está se referindo é a senha do conteúdo, que você pode definir para cada postagem e não é a mesma.

Mas como você deseja segmentar rotas existentes, como:

/wp/v2/cards
/wp/v2/cards/(?P<id>[\d]+)
/wp/v2/cards/...possibly some other patterns...

você pode tentar, por exemplo, o rest_dispatch_requestfiltro para configurar sua verificação de permissão adicional para esse tipo de rota.

Aqui está um plugin de demonstração:

add_filter( 'rest_dispatch_request', function( $dispatch_result, $request, $route, $hndlr )
{
    $target_base = '/wp/v2/cards';    // Edit to your needs

    $pattern1 = untrailingslashit( $target_base ); // e.g. /wp/v2/cards
    $pattern2 = trailingslashit( $target_base );   // e.g. /wp/v2/cards/

    // Target only /wp/v2/cards and /wp/v2/cards/*
    if( $pattern1 !== $route && $pattern2 !== substr( $route, 0, strlen( $pattern2 ) ) )
        return $dispatch_result;

    // Additional permission check
    if( is_user_logged_in() )  // or e.g. current_user_can( 'manage_options' )
        return $dispatch_result;

    // Target GET method
    if( WP_REST_Server::READABLE !== $request->get_method() ) 
        return $dispatch_result;

    return new \WP_Error( 
        'rest_forbidden', 
        esc_html__( 'Sorry, you are not allowed to do that.', 'wpse' ), 
        [ 'status' => 403 ] 
    );

}, 10, 4 );

onde segmentamos as rotas /wp/v2/cardse /wp/v2/cards/*GET, com verificações adicionais de permissão do usuário.

Ao depurá-lo com a autenticação de cookie do WordPress, podemos, por exemplo, testá-lo diretamente com:

https://example.tld/wp-json/wp/v2/cards?_wpnonce=9467a0bf9c

onde a parte nonce foi gerada a partir de wp_create_nonce( 'wp_rest' );

Espero que isto ajude!

Birgire
fonte
Tentei torná-lo geral para uma determinada base de destino, mas talvez haja uma maneira mais fácil de contornar isso? Eu adicionei um exemplo capacidade como um inline comentário @MarkKaplun
birgire
Talvez seja ainda mais simples remover o terminal de um determinado tipo de postagem personalizado, com o register_post_type_argsfiltro e, g, definido $args['show_in_rest'] = is_user_logged_in();para um determinado tipo de postagem ou com base nele $args['rest_base']. Não tenho certeza se isso é desejado ou recomendado ;-)
birgire
3

O campo "senha" que você está vendo não é realmente para a API REST, mas para a própria entrada Post. As postagens individuais no WordPress podem ser protegidas por senha, de modo que você precise da senha para ver o conteúdo.

Essa forma de pós-senha individual não é um mecanismo de senha forte, é uma senha compartilhada. A senha é a mesma para todos os usuários e é armazenada no banco de dados não criptografada e desmontada. Nunca foi concebido como um mecanismo seguro, por qualquer meio, é um mecanismo simples para ocultar o conteúdo de uma maneira simples.

Se você deseja usar esse mecanismo com a API REST, é possível. Por exemplo, se o ID da postagem individual for 123, uma postagem poderá ser recuperada da seguinte forma:

http://example.com/wp-json/wp/v2/posts/123

Se essa postagem estiver protegida por senha, esse URL a recuperará:

http://example.com/wp-json/wp/v2/posts/123?password=example-pass

Referência: https://developer.wordpress.org/rest-api/reference/posts/#retrieve-a-post

Se você precisar de uma autenticação mais forte e baseada no usuário, o WordPress oferecerá uma maneira de tornar as postagens "privadas". Essa configuração torna as postagens visíveis apenas para contas de usuário com o recurso "read_private_posts", limitado por padrão às funções de Administrador e Editor. (Nota: Privado apenas torna o conteúdo da postagem privado, seus títulos ainda podem ser expostos.)

Quando você cria um tipo de postagem personalizado, esse mesmo recurso é mapeado para o plural do seu tipo (usando o plural_base). Portanto, para um tipo de cartão de postagem, haveria uma permissão semelhante "read_private_cards" disponível para você atribuir às funções de usuário, se desejado.

Agora, a autenticação no nível do usuário não é realmente incorporada à API REST. A autenticação padrão baseada em cookies do WordPress funciona bem, no entanto, a API não oferece nenhuma maneira de obtê-lo. Ele será aceito se estiver presente, mas você deve executar o fluxo de login normal para obter um cookie. Se você quiser alguma outra abordagem de autenticação, precisará de um plugin.

Existem quatro desses plugins. São o OAuth 1.0, senhas de aplicativos, tokens JSON da Web e um plug-in de autenticação básica. Observe que a autenticação básica é mais fácil, porém também é insegura e, portanto, recomendada apenas para fins de teste e desenvolvimento. Não deve ser usado em um servidor de produção ao vivo.

Você pode encontrar mais informações sobre esses plugins aqui:

https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#authentication-plugins

Otto
fonte