ログインページを変える

ログインページを変える - ログインページをwp-login.phpから別ページに変える

説明

WordPressの標準的な不正ログイン対策としては、ログインIDは'admin'を避けるパスワードはユニークで長くする、場合によってはアクセスできるIPアドレスを制限する、といった具合だろう。これらの他に何かできないものだろうかと、ちょっと考えてみた。

きっかけは、日々のログに残っていくwp-login.phpのアクセス履歴。まあ、パス名はわかっているのだから、仕方ないないのかもしれない。逆にパス名がわからなければこんなアクセスは激減できるのではないだろうか。

ユニークなログインページを配置する

wp-login.phpの変わりとなる新しいログインページのソースコードは次の通り。

<?php
define( 'ANYWHERE_LOGIN', sha1( 'keyword' ) );
require_once './wp-login.php';
?>

このログインページのファイル名は任意で構わないが、適度に長いファイル名が望ましい(ここでは'anywhere-login.php')。配置場所は、wp-login.phpと同じディレクトリとする。
内容については、'ANYWHERE_LOGIN'を定義し、wp-login.phpを読み込んでいる。'keyword'については、適宜ユニークな文字に書き換えること。

テーマのfunctions.phpを書き換える

本当はプラグイン化すべきかもしれないが、ここは現在のテーマのfunctions.phpを書き換えることにする。追加する内容は次の通りだ。

define( 'ANYWHERE_LOGIN_PAGE', 'anywhere-login.php' );
add_action( 'login_init', 'anywhere_login_init' );
add_filter( 'site_url', 'anywhere_login_site_url', 10, 4 );
add_filter( 'wp_redirect', 'anywhere_login_wp_redirect', 10, 2 );
if ( ! function_exists( 'anywhere_login_init' ) ) {
	function anywhere_login_init() {
		if ( !defined( 'ANYWHERE_LOGIN' ) || sha1( 'keyword' ) != ANYWHERE_LOGIN ) {
			status_header( 403 );
			exit;
		}
	}
}
if ( ! function_exists( 'anywhere_login_site_url' ) ) {
	function anywhere_login_site_url( $url, $path, $orig_scheme, $blog_id ) {
		if ( ( $path == 'wp-login.php' || preg_match( '/wp-login\.php\?action=\w+/', $path ) ) &&
			( is_user_logged_in() || strpos( $_SERVER['REQUEST_URI'], ANYWHERE_LOGIN_PAGE ) !== false ) )
			$url = str_replace( 'wp-login.php', ANYWHERE_LOGIN_PAGE, $url );
		return $url;
	}
}
if ( ! function_exists( 'anywhere_login_wp_redirect' ) ) {
	function anywhere_login_wp_redirect( $location, $status ) {
		if ( strpos( $_SERVER['REQUEST_URI'], ANYWHERE_LOGIN_PAGE ) !== false )
			$location = str_replace( 'wp-login.php', ANYWHERE_LOGIN_PAGE, $location );
		return $location;
	}
}

ログインページ名は'ANYWHERE_LOGIN_PAGE'で定義し、'keyword'は新設するログインページしたものと同じものを指定すること。任意に変更するポイントはこの2箇所である。

login_initアクションはwp-login.php内で実行されるアクションで、ここでは先に設置したログインページ以外(wp-login.phpを含む)の場合、403エラーにしている。

site_urlフィルターは、ログイン済みか現在のページが今回設置したログインページの場合のみ、wp-login.phpを書き換えている。
ログイン済みの場合に書き換えている理由は、wp-adminディレクトリ以下のページでログアウトできるようにするため。現在のページが今回設置したログインページの場合に書き換えている理由は、入力したIDとパスワードを自身のページで受け取るためである。

wp_redirectフィルターは、ログアウト処理を終わった後に遷移するページを今回設置したログインページに変更している。

ログインからログアウトまでは大丈夫

一応シングルサイトにおいて、、新しいログインページでログインし、管理者ページでログアウトする一通りの動作は検証し、問題なく動作することは確認している(ただしマルチサイトでは未検証)。

制限としては、未ログイン状態でwp-adminディレクトリ以下のページにアクセスした際にログインページにリダイレクトするのだが、これについては新設したログインページが露出しないようwp-login.phpのままにしている(つまり、403エラーになる)。この点はご理解ください。


参考:
Login rebuilder:プラグイン作ってみました(本ページの内容をプラグイン化しました)

関連

お勧めコンテンツ

get_term_by(2010年1月5日 登録)

mixed get_term_by( string $field , mixed $value , string $taxonomy [ , string $output = OBJECT [ , string $filter = 'raw' ] ] )
ID、名前、スラッグを指定してカテゴリー・タグ情報を取得する。

get_previous_post(2010年5月24日 登録)

object get_previous_post( [ bool $in_same_cat$in_same_term = false [ , string $excluded_categoriesmixed $excluded_terms = '' [ , string $taxonomy = 'category' ] ] ] )
1つ前の投稿情報を取得する。

wp_nav_menu(2010年6月8日 登録)

string wp_nav_menu( [ array $args = array() ] )
ナビゲーションメニューを表示する(パラメータ'echo'がtrueの場合)。パラメータ'echo'がfalseの場合は、ナビゲーションメニューの文字列(HTMLコード)を返す。

untrailingslashit(2011年10月5日 登録)

string untrailingslashit( string $string )
末尾からスラッシュ(/)を取り除く。

maybe_unserialize(2013年4月27日 登録)

mixed maybe_unserialize( string $original )
シリアライズした文字列からアンシリアライズした値を取得する。

最終更新日時 : 2014-09-12 14:21