web-dev-qa-db-fra.com

Afficher le RSS externe protégé par mot de passe dans le modèle wordpress

J'utilise le code ci-dessous pour afficher un flux RSS externe dans mon modèle de page de blog wordpress:

<?php 
  include_once(ABSPATH . WPINC . '/rss.php');
  $rss = fetch_rss('http://feeds.feedburner.com/site-feed');
  $maxitems = 10;
  $items = array_slice($rss->items, 0, $maxitems);
?>
<ul class="arrow">
  <?php if (empty($items)): ?>
    <li>No items</li>
  <?php else:
      foreach ( $items as $item ):
        ?>
        <li>
          <a href='<?php echo $item['link']; ?>' title='<?php echo $item['title']; ?>'>
            <?php echo $item['title']; ?>
          </a>
        </li>
        <?php
      endforeach;
    endif;
  ?>

Le flux ci-dessus était précédemment ouvert mais est maintenant protégé par mot de passe Je connais déjà le nom d'utilisateur et le mot de passe. Comment modifier le code ci-dessus pour utiliser un mot de passe utilisateur/nom?

1
Skotlive

Je suppose que vous voulez dire chercher un flux externe avec une authentification HTTP .

Récupération de flux avec authentification HTTP

Notez que fetch_rss() utilise la bibliothèque MagPie , obsolète dans WordPress.

Utilisez plutôt fetch_feed() qui utilise la bibliothèque SimplePie .

Il semble que cela ne supporte pas ce genre d'URL:

http://user:[email protected]/feed/

comme nous pouvons utiliser avec curl en ligne de commande, par exemple:

# curl -i http://user:[email protected]/feed/

La fonction fetch_feed() appelle la fonction wp_safe_remote_request() pour extraire le flux. Cela se produit dans la classe WP_SimplePie_File, qui est une extension de la classe SimplePie_File.

C'est une bonne nouvelle, car cela signifie que nous pouvons utiliser le filtre http_request_args pour modifier les en-têtes de requête. Si nous vérifions la page Codex sur l'API HTTP HTTP , nous voyons que dans les références externes, il existe un lien vers le message court mais informatif de John Blackbourn sur Authentification de base avec l'API HTTP WordPress . Là, il donne l'exemple suivant:

$args = array(
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
    )
);
wp_remote_request( $url, $args );

envoyer l'en-tête d'authentification correct avec la demande.

Plugin de démonstration

Nous pouvons maintenant ajouter un support pour le type d'URL suivant:

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

avec le plugin this demo:

<?php
/**
 * Plugin Name: Fetch Feeds with http authentication
 * Description: Allows feeds urls like http://user:[email protected]/feed/
 * Plugin URI:  http://wordpress.stackexchange.com/a/199101/26350
 */    
add_action( 'wp_feed_options', function( $feed, $url )
{
    $user = parse_url( $feed->feed_url, PHP_URL_USER );
    $pass = parse_url( $feed->feed_url, PHP_URL_PASS );

    // Nothing to do
    if( ! $user || ! $pass )
        return;

    // Remove the user:pass@ part from the feed url
    $feed->feed_url = str_replace( 
        sprintf( '%s:%s@', $user, $pass ), 
        '', 
        $feed->feed_url
    );

    add_filter( 'http_request_args', function( $r, $url ) use ( $user, $pass )
    {
        // Add the user & pass to the request's header
        if( $user && $pass )
            $r['headers']['Authorization'] = 'Basic ' . base64_encode(  $user . ':' . $pass );
        return $r;
    }, 10, 2 );     

}, 10, 2 );

Mettre à jour:

Voici à quoi l'erreur ressemble:

WP HTTP Error: A valid URL was not provided.

quand on court:

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

Cela vient de la méthode WP_Http::request() :

if ( empty( $url ) || empty( $arrURL['scheme'] ) )
    return new WP_Error('http_request_failed', __('A valid URL was not provided.'));

Voici comment la fonction wp_safe_remote_request() est définie :

function wp_safe_remote_request( $url, $args = array() ) {
        $args['reject_unsafe_urls'] = true;
        $http = _wp_http_get_object();
        return $http->request( $url, $args );
}

Je jouais juste avec et testé:

$args['reject_unsafe_urls'] = false;

à travers:

add_action( 'wp_feed_options', function( $feed )
{
    $user = parse_url( $feed->feed_url, PHP_URL_USER );
    $pass = parse_url( $feed->feed_url, PHP_URL_PASS );

    if( ! $user || ! $pass )
        return;

    add_filter( 'http_request_args', function( $r, $url ) use ( $user, $pass )
    {
        if( $user && $pass )
            $r['reject_unsafe_urls'] = false;
        return $r;
    }, 10, 2 );     
} );

et puis cela a fonctionné:

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

Dans la méthode WP_Http::request(), nous avons cette condition:

if ( $r['reject_unsafe_urls'] )
    $url = wp_http_validate_url( $url );

il semble donc que wp_http_validate_url() ne valide pas cette URL:

http://user:[email protected]/feed/

En définissant reject_unsafe_urls sur false, nous ignorons cette vérification.

Il existe en fait un filtre pour ceci: http_request_reject_unsafe_urls, mais je ne recommanderais pas d'utiliser:

add_filter( `http_request_reject_unsafe_urls`, '__return_false' );

Je pense que le plugin de démonstration ci-dessus serait en général un meilleur choix, car il utilise toujours la fonction wp_http_validate_url() sur l'URL dépouillé avec authentification.

Remarque:

Cette partie :

if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
    return false;

dans la fonction wp_http_validate_url(), il semble que soit le show-stopper pour fetch_feed() pour les URL avec utilisateur: pass .

2
birgire