セキュリティ 2025.11.11 2025.11.12
WordPressでログイン履歴を確認する2つの方法を解説。サンプルコードあり

「WordPressに不具合が発生した」
「不正アクセスを受けた可能性がある」
そんな時はログイン履歴を確認することが有効です。
ただ、ログイン履歴をどうやって確認すれば良いか、ご存じない方も多いと思います。
そこで、今回はWordPressのログイン履歴を確認する方法を解説。functions.phpに追加するだけで、管理画面内でログイン履歴を確認できるサンプルコードも紹介します。
ログイン履歴の確認が必要な理由や、第三者からのログインを防ぐセキュリティの強化方法もまとめているので、ぜひご覧ください。
WordPressでログイン履歴を確認するべき理由
まずは、WordPressのログイン履歴を確認することで何がわかるのか?
ログイン履歴を確認するべき理由について見ていきましょう。
不正アクセスを早期発見するため
WordPressに限った話ではありませんが、システムやネットワークは常に不正アクセスの危機に晒されています。Webサイトの場合、不正アクセスの被害に遭うことで、悪質なサイトへの外部リンクが勝手に貼られてしまったり、メール送信機能の悪用によりスパムメールを送信されてしまったりする恐れがあります。
WordPressは適切に運用すれば高いセキュリティ水準を保てますが、ユーザー数が多いことから攻撃者に狙われやすいという実態があります。
ログイン履歴を確認する習慣があれば、万が一海外IPからのアクセスや深夜帯の不審なアクセスがあっても素早く察知でき、適切な対処をすることが可能です。
WordPressの不正アクセスを調査する方法とその対策を徹底解説
複数ユーザーの操作状況を把握するため
ログイン履歴を確認する習慣は、万が一トラブルが起きた際の対処として有用です。
複数ユーザーでWebサイトを運用している場合、ログイン履歴を確認できる仕組みを導入しておけば、「誰が・いつ」ログインしたかを明確にできます。社内の運用メンバー同士はもちろん、サイトの運用に社外の制作会社やWebライターなどが関わっている場合、責任範囲を明確にすることができるのです。
トラブル発生時の原因を特定するため
ログイン履歴を確認する理由は、トラブル発生時の責任範囲を明確にすることだけに留まりません。例えばエラーやレイアウト崩れなどが起きた際に、ログイン履歴を確認することで、なんらかの作業が行われたタイミングを追跡することも可能です。
作業のタイミングから、その時間帯にWordPressを使用していたユーザーを特定すれば、トラブルの原因を突き止めたり、復旧の足掛かりにしたりできます。
コンプライアンスや監査に対応するため
こちらはログイン履歴の確認というよりも、確認のために行う「保存」という手段が重要です。
サイトの性質によっては、個人情報保護法や内部統制の観点から「誰が」「いつ」「どこから」アクセスしたかという情報を記録しておくことが求められます。ログイン履歴を一定期間保存することで、このアクセス記録保持の要件を満たしやすいため、履歴の確認と並行して実施することが推奨されます。
1.プラグインを使用してログイン履歴を確認する方法
ここからは、実際にWordPressのログイン履歴を確認する方法を解説していきます。最初に解説するのは、プラグインを使用する方法です。
なお、この後プラグインを使用せずログを確認する方法もご紹介しますが、そちらはサーバーの知識が必須なので、WordPress初心者はプラグインを使用する方法をおすすめします。
1.プラグインをインストールする
はじめに、ログイン履歴を確認できる機能が備わったプラグインをインストールします。今回の解説では「SiteGuard WP Plugin」を使用します。
公式サイトから直接インストールするか、もしくは管理画面にログインし、「プラグイン>プラグインを追加」から検索してインストールしてください。
2.WordPressの管理画面にログインする
続いてプラグインを有効化するために、管理画面にログインします。管理画面から検索してプラグインをインストールした場合はそのままで問題ありません。
公式サイトからインストールした場合は「プラグイン>インストール済みプラグイン」からプラグインを有効化します。
管理画面から検索してインストールした場合は「今すぐインストール」ボタンが「有効化」に変わっているので、そこをクリックします。
3.ログイン履歴を選択する
正しく有効化できると、メニューに「SiteGuard」の項目が追加されます。クリックして進み、「ログイン履歴」を選択すると、ログインがあった日時やログイン名、IPアドレスなどを確認できます。
2.functions.phpを使用してログイン履歴を取得する方法
もう1つ、プラグインに頼らない方法として、functions.phpを使用する方法をご紹介します。
こちらはfunctions.phpのファイル内に、以下のコードを追加するだけです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
/** * ログイン履歴の取得 * - ログイン成功/失敗の監査ログを options に保存し、管理画面(ツール配下)で閲覧・CSV書き出し・全消去を提供 */ defined('ABSPATH') || exit; // ============================== // 設定値(オプション名・最大件数・1ページ表示件数) // ============================== if (!defined('CLH_OPTION_NAME')) { define('CLH_OPTION_NAME', 'clh_login_logs'); // 監査ログを保存するオプション名 } if (!defined('CLH_MAX_LOGS')) { define('CLH_MAX_LOGS', 300); // 保存件数の上限 } if (!defined('CLH_PER_PAGE')) { define('CLH_PER_PAGE', 50); // 管理画面での1ページ当たり表示件数 } // 信頼プロキシ(CDN/ロードバランサ等)の背後で X-Forwarded-For を採用するか // 必要に応じて wp-config.php 等で true にしてください。 if (!defined('CLH_TRUST_PROXY')) { define('CLH_TRUST_PROXY', false); } // ============================== // 初期化:オプション作成(autoload=off) // ============================== add_action('init', function () { // 初回のみ空配列でオプション作成(autoload=no でメモリ常駐を避ける) if (false === get_option(CLH_OPTION_NAME, false)) { add_option(CLH_OPTION_NAME, [], '', 'no'); } }); // ============================== // 補助:クライアントIPの安全取得 // ============================== /** * 可能なHTTPヘッダを優先順に評価し、X-Forwarded-Forは(信頼プロキシ時のみ)先頭IPを採用。 * IPv4/IPv6の形式検証も行う。取得できなければ '0.0.0.0' を返す。 * 必要に応じて clh_client_ip フィルタで匿名化/上書き可能。 */ function clh_get_client_ip(): string { $candidates = array_filter([ 'HTTP_CLIENT_IP', // XFF は信頼プロキシ配下のみ採用(先頭IP) CLH_TRUST_PROXY ? 'HTTP_X_FORWARDED_FOR' : null, 'HTTP_X_REAL_IP', 'REMOTE_ADDR', ]); foreach ($candidates as $key) { if (!empty($_SERVER[$key])) { $raw = $_SERVER[$key]; if ($key === 'HTTP_X_FORWARDED_FOR' && strpos($raw, ',') !== false) { $parts = array_map('trim', explode(',', $raw)); $raw = $parts[0] ?? $raw; } if (filter_var($raw, FILTER_VALIDATE_IP)) { // 必要に応じて匿名化や上書きを許可 $raw = apply_filters('clh_client_ip', $raw, $key); return $raw; } } } return '0.0.0.0'; } // ============================== // 補助:mbstring 非搭載環境フォールバック付トランケート // ============================== if (!function_exists('clh_truncate_ua')) { function clh_truncate_ua(string $ua, int $len = 512): string { if (function_exists('mb_substr')) { return mb_substr($ua, 0, $len); } return substr($ua, 0, $len); } } // ============================== // ログイン成功時の記録 // ============================== /** * 成功イベント(wp_login)でユーザー名・ID・IP・UA・時刻を配列に追記。 * 保存件数上限を超えた場合は古いものから削除。 */ function clh_record_login_success($user_login, $user) { if (!is_a($user, 'WP_User')) return; $ip_address = clh_get_client_ip(); $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : ''; $user_agent = clh_truncate_ua($user_agent, 512); // UAの長さ制限(mbstring対応) $time = current_time('mysql'); $logins = get_option(CLH_OPTION_NAME, []); if (!is_array($logins)) $logins = []; $logins[] = [ 'status' => 'success', 'user_login' => sanitize_text_field($user_login), 'user_id' => (int) $user->ID, 'ip' => $ip_address, 'user_agent' => $user_agent, 'time' => $time, ]; // 上限超過分を先頭から切り捨て $excess = count($logins) - CLH_MAX_LOGS; if ($excess > 0) { $logins = array_slice($logins, $excess); } // 第3引数falseでautoload設定を維持 update_option(CLH_OPTION_NAME, $logins, false); } add_action('wp_login', 'clh_record_login_success', 10, 2); // ============================== // ログイン失敗時の記録(任意) // ============================== /** * 失敗イベント(wp_login_failed)で同様に監査ログを追記。 * ブルートフォース検知や分析に有用。 */ function clh_record_login_failed($username) { $ip_address = clh_get_client_ip(); $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : ''; $user_agent = clh_truncate_ua($user_agent, 512); $time = current_time('mysql'); $logins = get_option(CLH_OPTION_NAME, []); if (!is_array($logins)) $logins = []; $logins[] = [ 'status' => 'failed', 'user_login' => sanitize_text_field((string) $username), 'user_id' => 0, 'ip' => $ip_address, 'user_agent' => $user_agent, 'time' => $time, ]; $excess = count($logins) - CLH_MAX_LOGS; if ($excess > 0) { $logins = array_slice($logins, $excess); } update_option(CLH_OPTION_NAME, $logins, false); } add_action('wp_login_failed', 'clh_record_login_failed'); // ============================== // 管理メニュー:ツール配下に「ログイン履歴」を追加 // ============================== add_action('admin_menu', function () { add_submenu_page( 'tools.php', // 親メニュー 'ログイン履歴', // ページタイトル 'ログイン履歴', // メニュータイトル 'manage_options', // 権限 'custom-login-history', // スラッグ 'clh_display_login_history' // 表示コールバック ); }); // ============================== // 管理画面アクション:CSVエクスポート // ============================== /** * admin-post の非公開エンドポイントでCSVを生成して出力。 * 権限とnonceでCSRF対策。Excel互換のためBOM・式注入対策あり。 */ add_action('admin_post_clh_export', function () { if (!current_user_can('manage_options') || !check_admin_referer('clh_export')) { wp_die('Permission denied.'); } $logins = get_option(CLH_OPTION_NAME, []); nocache_headers(); header('Content-Type: text/csv; charset=UTF-8'); header('Content-Disposition: attachment; filename=login-history.csv'); $out = fopen('php://output', 'w'); // Excel 互換のための BOM 付与(日本語文字化け回避) fwrite($out, chr(0xEF) . chr(0xBB) . chr(0xBF)); // 式注入対策: 先頭が = + - @ の値は無害化する $neutralize = function ($v) { $v = (string) $v; if ($v !== '' && in_array($v[0], ['=', '+', '-', '@'], true)) { return "'" . $v; } return $v; }; fputcsv($out, ['status','user_login','user_id','ip','user_agent','time']); // ヘッダー行 foreach ($logins as $row) { $status = $neutralize($row['status'] ?? ''); $user_login = $neutralize($row['user_login'] ?? ''); $user_id = (int) ($row['user_id'] ?? 0); $ip = $neutralize($row['ip'] ?? ''); $ua = $neutralize($row['user_agent'] ?? ''); $time = $neutralize($row['time'] ?? ''); fputcsv($out, [$status, $user_login, $user_id, $ip, $ua, $time]); } fclose($out); exit; }); // ============================== // 管理画面アクション:全履歴削除 // ============================== /** * 同じくadmin-postで履歴を空にしてツールページへリダイレクト。 */ add_action('admin_post_clh_clear', function () { if (!current_user_can('manage_options') || !check_admin_referer('clh_clear')) { wp_die('Permission denied.'); } update_option(CLH_OPTION_NAME, [], false); wp_safe_redirect(add_query_arg(['page' => 'custom-login-history', 'clh' => 'cleared'], admin_url('tools.php'))); exit; }); // ============================== // 管理画面:履歴一覧の描画(ページネーションあり) // ============================== /** * オプションからログ配列を取得して新しい順で表示。 * ページネーション・CSV出力・全削除ボタンを設置(nonce付)。 */ function clh_display_login_history() { if (!current_user_can('manage_options')) return; $logins = get_option(CLH_OPTION_NAME, []); $logins = is_array($logins) ? $logins : []; $logins = array_reverse($logins); // 新しい順へ // ページング情報の算出 $paged = max(1, (int) ($_GET['paged'] ?? 1)); $total = count($logins); $pages = max(1, (int) ceil($total / CLH_PER_PAGE)); $offset = ($paged - 1) * CLH_PER_PAGE; $rows = array_slice($logins, $offset, CLH_PER_PAGE); // CSV/削除のURL生成(nonce付与) $export_url = wp_nonce_url(admin_url('admin-post.php?action=clh_export'), 'clh_export'); $clear_url = wp_nonce_url(admin_url('admin-post.php?action=clh_clear'), 'clh_clear'); echo '<div class="wrap">'; echo '<h1 style="margin-bottom:14px;">ログイン履歴</h1>'; // 削除後のフラッシュメッセージ if (isset($_GET['clh']) && $_GET['clh'] === 'cleared') { echo '<div class="notice notice-success"><p>履歴を削除しました。</p></div>'; } // 説明文&操作ボタン echo '<p>直近の最大' . esc_html((string) CLH_MAX_LOGS) . '件の情報が表示されます。</p>'; echo '<p style="margin:12px 0;">'; echo '<a class="button button-secondary" href="' . esc_url($export_url) . '">CSVエクスポート</a> '; echo '<a class="button button-secondary" href="' . esc_url($clear_url) . '" onclick="return confirm(\'本当に全ての履歴を削除しますか?\');">全て削除</a>'; echo '</p>'; // 一覧テーブル echo '<table class="widefat fixed striped">'; echo '<thead><tr>'; echo '<th>ステータス</th><th>ユーザー名</th><th>User ID</th><th>IPアドレス</th><th>使用デバイス/ブラウザ</th><th>時刻</th>'; echo '</tr></thead><tbody>'; if (!empty($rows)) { foreach ($rows as $log) { echo '<tr>'; echo '<td>' . esc_html($log['status'] ?? '') . '</td>'; echo '<td>' . esc_html($log['user_login'] ?? '') . '</td>'; echo '<td>' . esc_html((string) ($log['user_id'] ?? 0)) . '</td>'; echo '<td>' . esc_html($log['ip'] ?? '') . '</td>'; echo '<td>' . esc_html($log['user_agent'] ?? '') . '</td>'; echo '<td>' . esc_html($log['time'] ?? '') . '</td>'; echo '</tr>'; } } else { echo '<tr><td colspan="6">ログイン履歴はありません。</td></tr>'; } echo '</tbody></table>'; // ページナビゲーション(tools サブページ維持) if ($pages > 1) { echo '<div class="tablenav"><div class="tablenav-pages">'; $current_page_slug = 'custom-login-history'; for ($i = 1; $i <= $pages; $i++) { $url = add_query_arg( ['page' => $current_page_slug, 'paged' => $i], admin_url('tools.php') ); $class = $i === $paged ? ' class="page-numbers current"' : ' class="page-numbers"'; echo '<a' . $class . ' href="' . esc_url($url) . '">' . esc_html((string) $i) . '</a> '; } echo '</div></div>'; } echo '</div>'; } |
これにより管理画面の「ツール>ログイン履歴」から
- ユーザー名
- IPアドレス
- 使用デバイス/ブラウザ
- ログイン時刻
が確認できるようになります。
functions.phpにコードを追加するには、WordPressの管理画面から「外観 > テーマファイルエディタ」で編集したり、FTP接続して直接編集するといった方法があります。
ただし、functions.phpはサイト全体に影響があるファイルなので、操作の前には必ずバックアップを取得してすぐに戻せるようにしておきましょう。知識がなくて不安な場合は、エンジニアに依頼することも検討してください。
詳しくは、以下の記事もあわせて参照してください。
意外と簡単!自作のWordPressテーマの作り方から適用までを解説
WordPressでログイン履歴を確認できるおすすめプラグイン
WordPressでログイン履歴を確認できるようにするためのプラグインは複数ありますが、今回は2つ、おすすめのものをご紹介します。
SiteGuard WP Plugin:総合的なセキュリティ対策をしたい方向け
先ほど名前だけ挙げた「SiteGuard WP Plugin」は、ログイン履歴の確認以外にも広いセキュリティ対策が可能となっており、中でもログイン攻撃に特化しています。
- ログインしていないユーザーからの管理画面へのアクセスをブロックする
- ログインページのURLを変更する
- 指定回数、ログインに失敗したIPアドレスを一定時間ブロックする
- ログインがおこなわれた際に、ログインユーザーにメールで通知する
他にも複数の機能が備わっているので、ログイン履歴の確認に加えて総合的なセキュリティ対策をしたい方におすすめです。
User Login History:ログイン履歴だけ確認したい方向け
「User Login History」は、ログイン履歴の確認に特化したプラグインです。ログインに関するさまざまな内容を確認でき、以下がその一例です。
- ログイン・ログアウト日時
- 最終閲覧日時
- ログインステータス(ログイン/ログアウト/失敗)
- ユーザーID
- ユーザー名
- IPアドレス
- 国名・国コード
- タイムゾーン
本プラグインは無料でダウンロードできますが、さらに機能が充実した有料版も用意されています。有料版はIP アドレスを制御する、ログインが成功or失敗した時にメールで通知する、IPアドレスに基づいてログイン回数のレポートを生成するなどの機能が追加で利用できます。
一般的なセキュリティは他のプラグインに任せて、ログイン履歴に関連するセキュリティ機能だけ追加したい方におすすめです。
第三者からのログインを防ぐセキュリティの強化方法
ここまでログイン履歴を確認する方法や、そのためのプラグインをご紹介しましたが、実際には第三者からログインされた後に気づくよりも、ログイン自体を防ぐことのほうが遥かに重要です。
そこで、第三者からのログインを防ぐセキュリティの強化方法もご紹介します。
なお、不正ログイン対策については別の記事でも解説していますので、ぜひあわせて参考にしてください。
WordPressの不正ログイン対策7つと誤った対策方法について
独自のユーザー名・パスワードを設定する
ログインする際に必要なユーザー名とパスワードの文字列を独自のものにすることは、セキュリティ対策の基本です。
推測されにくいユーザー名とパスワードを設定することで、第三者にログインされるリスクを軽減できます。具体的には大文字・小文字・数字・記号を織り交ぜた10文字以上の文字列を設定しましょう。この時、名前や企業名、サイト名など、予測されやすい文字列を使用しないことも重要です。
また、他のWebサイトからユーザー名やパスワードを使い回すと不正ログインのリスクが高まってしまいますので、あわせてご注意ください。
ログイン画面のURLを変える
管理画面のURLはデフォルトだと「https://ドメイン名/wp-login.php」となっています。この状態だと、ドメイン名を知っている人ならば第三者でも管理画面にアクセスできてしまいます。このためURLを変更し、管理画面へのアクセスを制限することが推奨されます。
管理画面のURLを変更するには、前述した「SiteGuard WP Plugin」をはじめとしたプラグインが有効です。
また、デフォルトの設定では管理画面URL(/wp-admin/)にアクセスすると自動でログイン画面にリダイレクトしてしまい、せっかくログイン画面のURLを変更した意味が薄くなってしまいます。そのため、ログイン画面URLを変更する際は、非ログイン時に管理画面にアクセスした場合にログイン画面にリダイレクトしないように設定しておきましょう。
IP制限をかける
ログイン画面や管理画面にアクセスできるIPアドレスを制限することで、外部からのアクセスを防ぐことができます。IP制限をかける方法は、プラグイン「SiteGuard WP Plugin」を使用する方法と、サーバーやファイアウォールで設定する方法の2つがあります。
後者はサーバーの設定に手を加えなければならず、知識がなければ少々難易度が高いです。初心者の方はプラグインを使用する方法をおすすめします。
一般ユーザーのログイン履歴を取得する場合は、プライバシーポリシーに留意
最後に注意点をお話しします。
IPやユーザー名は個人情報に該当し得るため、外部のユーザーがログインするようなWebサイトの場合、ログイン履歴を取得する機能を追加する際は、管理者がログイン履歴を確認する旨とその目的をプライバシーポリシー(個人情報保護方針)記述しておく必要があります。
例えば会員制のWebサイトなどの場合、プライバシーポリシーに「ログイン監査目的で保存する」という内容を追記します。
なお、社内の運用メンバーやサイト開発者など、内部の人間しかサイトにログインしない場合は特に気にする必要はありません。
まとめ
WordPressのログイン履歴を確認することは、セキュリティ向上やトラブル回避・対処の観点から重要です。
ログイン履歴を確認する方法は複数ありますが、特に理由がなければプラグインを使用することをおすすめします。難しい知識が不要なので、初心者の方でも簡単に履歴を確認できるようになります。
もちろん、ベストなのは第三者のログイン自体を事前に防げることなので、ログイン履歴を確認するだけではなく、その他の不正ログイン対策も徹底しましょう。
より徹底したセキュリティ対策をご希望の場合はwp.makeにお任せください。WordPressを専門に扱うプロが、圧倒的なノウハウを用いて安心・安全なセキュリティ環境を提供いたします。
wp.make WordPress保守運用・セキュリティ対策の詳細はこちら
WordPress保守・運用のパートナーなら「wp.support」にお任せ!
WordPressサイトを運用していて、以下のようなお悩みはありませんか?
- 管理画面を使いやすくしたいけれど、カスタマイズする時間や技術がない…
- サイトのUI/UXを改善したいけれど、自社内では難しい…
- WordPressサイトを高速化したいけれど、ノウハウがない…
- セキュリティ対策をしたいけれど、知識のある人材がいない…
- 日々の業務に追われて、バージョンアップなどの保守業務が放置気味…
- ちょっとしたトラブルを気軽に相談できる相手が欲しい…
「wp.support」は、WordPressのプロフェッショナル集団によるWordPress保守サービスです。
「セキュリティ対策」「バージョンアップ対応」「定期バックアップ」はもちろん、「電話サポートが無制限」なのでカスタマイズの方法やトラブル発生時にも気軽にプロに相談できます。
既に導入済みのお客様からも、
「些細なことでも気軽に相談できるパートナー的な存在」
「困ったら相談していいんだ、と気持ちが楽になった」
と大変ご好評をいただいています。
WordPress保守・運用のパートナーをお探しなら、ぜひお気軽にお問合せください。
バージョンアップが面倒だと思ったら WordPress保守・セキュリティ対策は『wp.support』にお任せ!
WordPressのバージョンアップやセキュリティ対策にお悩みではないですか?
面倒な保守・運用作業は全て任せて、コア事業に集中してください。
大手・上場企業100社以上のWebサイトの安全を守る、WordPressのプロフェッショナル集団が、あなたのWordPressサイトを守ります!
【対応範囲】
・WordPress、プラグインのバージョンアップ ・セキュリティ対策 ・継続的なバックアップ ・緊急時の復旧対応 ・技術サポート・電話/メールサポート無制限 etc...
WordPressに関することなら何でもご相談ください!







