在WordPress模板中显示受密码保护的外部RSS

时间:2015-08-19 作者:Skotlive

我正在使用以下代码在wordpress博客页面模板中显示外部rss源:

<?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;
  ?>
上面的提要先前已打开,但现在受密码保护。我已经知道用户名和密码了。如何调整上述代码以使用用户名密码?

1 个回复
SO网友:birgire

我想您的意思是使用HTTP身份验证获取外部提要。

使用HTTP身份验证获取提要请注意fetch_rss() 使用WordPress中不推荐使用的MagPie库。

改用fetch_feed() 它使用SimplePie库。

看起来它不支持这种url:

http://user:[email protected]/feed/
就像我们可以使用curl 在命令行中,例如:

# curl -i http://user:[email protected]/feed/
Thefetch_feed() 函数调用wp_safe_remote_request() 函数,以获取提要。这是在WP_SimplePie_File 类,这是SimplePie_File

这是个好消息,因为这意味着我们可以使用http_request_args 过滤器,以修改请求标头。如果我们查看HTTP API, 我们在外部参考资料中看到,有一个链接指向约翰·布莱克本(JohnBlackbourn)关于Basic Authentication with the WordPress HTTP API. 在这里,他给出了以下示例:

$args = array(
    \'headers\' => array(
        \'Authorization\' => \'Basic \' . base64_encode( YOUR_USERNAME . \':\' . YOUR_PASSWORD )
    )
);
wp_remote_request( $url, $args );
将正确的身份验证标头与请求一起发送。

演示插件现在可以添加对以下url类型的支持:

$rss = fetch_feed( \'http://user:[email protected]/feed/\' );
使用此演示插件:

<?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 );
更新:

错误如下:

WP HTTP Error: A valid URL was not provided.
当我们运行时:

$rss = fetch_feed( \'http://user:[email protected]/feed/\' );
它来自WP_Http::request() method:

if ( empty( $url ) || empty( $arrURL[\'scheme\'] ) )
    return new WP_Error(\'http_request_failed\', __(\'A valid URL was not provided.\'));
以下是wp_safe_remote_request() 函数为defined:

function wp_safe_remote_request( $url, $args = array() ) {
        $args[\'reject_unsafe_urls\'] = true;
        $http = _wp_http_get_object();
        return $http->request( $url, $args );
}
我只是在玩它并测试:

$args[\'reject_unsafe_urls\'] = false;
通过:

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 );     
} );
然后这就奏效了:

$rss = fetch_feed( \'http://user:[email protected]/feed/\' );
内部WP_Http::request() 方法我们得到这个条件:

if ( $r[\'reject_unsafe_urls\'] )
    $url = wp_http_validate_url( $url );
所以看起来wp_http_validate_url() 未验证此url:

http://user:[email protected]/feed/
按设置reject_unsafe_urls 若为false,则跳过该检查。

实际上有一个过滤器可用于此:http_request_reject_unsafe_urls, 但我不建议使用:

add_filter( `http_request_reject_unsafe_urls`, \'__return_false\' );
我认为上面的演示插件通常是更好的选择,因为它仍然使用wp_http_validate_url() 在授权剥离url上。

注:

This part:

if ( isset( $parsed_url[\'user\'] ) || isset( $parsed_url[\'pass\'] ) )
    return false;
wp_http_validate_url() 功能,似乎是fetch_feed() 对于带有用户:pass的URL。

结束

相关推荐

Randomizing the RSS Widget

我想看看是否有一种方法可以让RSS小部件拉入不同的提要(比如说我选择了十个提要之一),并在每次刷新页面时将其显示在小部件中?有点像这个帖子(Different rss feeds in a single dashboard widget) 除了这个人试图一次显示多个提要,我想在每次刷新页面或转到其他页面时将其从一个提要旋转到另一个提要。所以它只显示一个提要,但每次都不同。