WordPress:ユーザーページ、日付ページを非表示にする

WordPress:ユーザーページ、日付ページを非表示にする

これまであまり気にしていなかったのですが、WordPress はブログシステムですので、投稿ページだけではなくユーザーページや日付ページなど、公開しようと思っていないページまでデフォルトで表示するようになっています。

どのように表示されるかを意図していないページまで表示されるのは不本意ですので非表示にしようと思います。また、セキュリティ上、ログインにアクセス制限をかけるか、ログインページを変更していない場合は、ユーザーページは非表示にすべきです。

01template_redirect でホームページに飛ばす

まず、セキュリティ上の問題を考慮せず単に公開する予定のないページを非表示にする場合です。方法はいろいろあるとは思いますが、簡単なのはアクションフック template_redirect でホームページや 404ページに飛ばすことかと思います。

function custom_redirects() {
	if ( is_author() ) {
		wp_redirect( home_url( '/' ) );
		die;
	}
	if ( is_date() ) {
		wp_redirect( home_url( '/' ) );
		die;
	}
}
add_action( 'template_redirect', 'custom_redirects' );

WordPress Developer Resources にあるコードそのままですが、これでユーザーページや日付ページにアクセスがあった場合はホームページにリダイレクトします。

02セキュリティ対策としてユーザー名を隠したい場合

ただ、これではセキュリティ対策としてユーザー名を隠したいという場合は意味がありません。あえてユーザー名を見ようと思う人には効果がないということです。

通常、ブラウザに //ドメイン名/?author=1 と打てば //ドメイン名/author/管理者ユーザー名/ にリダイレクトされ管理者のユーザー名が表示されてしまいます。前項目の template_redirect でもこのブラウザからのアクセスならユーザー名を隠せますが、端末、あるいはコマンドプロンプトから curl http(s)://ドメイン/?author=1 -v と打てばユーザー名が表示されてしまいます。

これを防ぐには元から絶たなきゃダメです。これにもいろいろあるようですが、そのひとつとして多く使われているコードが次のものです。

function disable_author_archive() {
    if ( $_GET['author'] || preg_match('#/author/.+#', $_SERVER['REQUEST_URI']) ) {
        wp_redirect(home_url('/404.php'));
        //または wp_redirect(home_url(''));
        die;
    }
}
add_action ('init', 'disable_author_archive');

このコードを functions.php に書き加えれば、前項目のリダイレクトがなくてもユーザーページは表示されなくなり、また、curl http(s)://ドメイン/?author=1 -v と打ってもユーザ名は表示されなくなります。

ただ、これでも完全にユーザー名を隠せるわけではありません。最終的には //ドメイン/wp-json/ をふさがないとユーザー名を隠すことはできません。この状態でブラウザに //ドメイン/wp-json/wp/v2/users/1 と打ちますと、

こんな風にユーザー名が表示されてしまいます。グレーにマスクしてある部分です。

03WP REST API を無効にする

このあたりになりますとかなり難しくなってきます。WordPress には WP REST API というものが搭載されており、外部からブラウザを介さなくても WordPress の持っているデータを取り出すことができるようになっています。もちろんなんでも取り出せるわけではありませんが、取り出せるものの中にユーザー情報も入っているということです。それが上の画像で示したものです。

ただ、この WP REST API は管理画面やプラグインで使用されていますので無闇に閉じてしまいますとサイトが機能しなくなってしまいます。たとえば、次のコードを fuctions.php に書けば完全に API を塞ぐことが出来ますが、ブロックエディタなど管理画面で使えないもので出てきます。

add_filter( 'rest_endpoints', function( $endpoints ) {
    $endpoints = [];
    return $endpoints;
});

じゃあ、この $endpoints のユーザー情報だけ閉じることはできないとかということで次のコードを入れてみますと //ドメイン/wp-json/wp/v2/users///ドメイン/wp-json/wp/v2/users/1 に対して 404 を返してきます。

add_filter( 'rest_endpoints', function( $endpoints ) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'] );
    }
    if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
        unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
    }
    return $endpoints;
});

これでいけるんじゃないかと思いますが、ネット上でたくさん公開されているのは次のコードです。ただ、私は使っていませんので調べていませんが、プラグインの Contact Form7 が使えなくなるという記事もあります。

add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }
    if ( ! is_user_logged_in() ) {
        return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
    }
    return $result;
});

04ログインページを変更する

以上、ユーザー名を隠す方法をいくつかやってきましたが、私はユーザー名が表に出ることにあまりこだわっても生産性がないように思います。むしろログインや管理画面にアクセス制限をかけたり、ログインページを変更するほうがより有効かとは思います。

方法はググればたくさんヒットしますし、後日あらためてまとめようかとは思います。