私は私のワードプレスのブログページのテンプレートで外部の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;
?>
上記のフィードは以前オープンしていましたが、現在はパスワードで保護されています。私はすでにユーザー名とパスワードを知っています。ユーザー/名前パスワードを使用するために上記のコードを微調整するにはどうすればいいですか?
HTTP認証 を使って外部フィードを取得するという意味です。
fetch_rss()
は MagPie ライブラリを使うことに注意してください。これはWordPressでは非推奨です。
代わりに SimplePie ライブラリを使用するfetch_feed()
を使用してください。
それはこの種類のURLをサポートしていないけれどもそれは見えます:
http://user:[email protected]/feed/
コマンドラインでcurl
と一緒に使うことができるように、例えば:
# curl -i http://user:[email protected]/feed/
fetch_feed()
関数は、フィードを取得するためにwp_safe_remote_request()
関数を呼び出します。これはWP_SimplePie_File
クラスで起こります。これはSimplePie_File
クラスの拡張です。
これは良いニュースです。なぜなら、リクエストヘッダを修正するためにhttp_request_args
フィルタを使用できるからです。 HTTP API のCodexページをチェックアウトすると、外部参照でJohn Blackbournの短くて有益な投稿へのリンクがあることがわかります。 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()
メソッド からきています。
if ( empty( $url ) || empty( $arrURL['scheme'] ) )
return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
これがwp_safe_remote_request()
関数が どのように定義されているかです :
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' );
私は上記のデモプラグインは、一般的にはより良い選択であると思います。なぜなら、それは認証ストリップURLのwp_http_validate_url()
をまだ使用しているからです。
この部分 :
if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
return false;
wp_http_validate_url()
関数内では、 show:stop のような user:pass のURLのfetch_feed()
が表示されます。