WordPressではログイン成功・失敗の通知をしっかり管理することで、セキュリティの強化や管理ログの記録が可能になります。
本記事では、Chatwork / Slack / メールの3系統へ同時通知できる**ログイン通知プラグイン(Multi Login Notifier Extended)**の導入方法と全ソースコードを紹介します。
特徴
- ログイン成功時に通知
- ログイン失敗時にも通知
- 通知先:
- Chatwork(トークン+ルームID)
- Slack(Webhook URL)
- メール(任意の宛先)
- 通知対象:
- 指定ロールのユーザーのみ通知
- 除外ユーザー名も指定可能
- 管理画面で設定可能
ファイル構成
multi-login-notifier-extended/
├── multi-login-notifier-extended.php
└── includes/
└── settings.php
multi-login-notifier-extended.php
<?php
/**
* Plugin Name: Multi Login Notifier Extended
* Description: Chatwork、Slack、メールにログイン成功・失敗通知を送信し、対象ロールや除外ユーザーも指定できるWordPressプラグイン
* Version: 1.1.0
* Author: Your Name
*/
defined('ABSPATH') || exit;
require_once plugin_dir_path(__FILE__) . 'includes/settings.php';
add_action('wp_login', 'mln_notify_on_login', 10, 2);
function mln_notify_on_login($user_login, $user) {
$excluded_users = array_map('trim', explode(',', get_option('mln_excluded_users', '')));
if (in_array($user_login, $excluded_users, true)) return;
$allowed_roles = array_map('trim', explode(',', get_option('mln_allowed_roles', '')));
if (!empty($allowed_roles)) {
$matched = false;
foreach ($user->roles as $role) {
if (in_array($role, $allowed_roles, true)) {
$matched = true;
break;
}
}
if (!$matched) return;
}
$site_name = get_bloginfo('name');
$site_url = home_url();
$ip_address = $_SERVER['REMOTE_ADDR'];
$login_time = current_time('mysql');
$roles = implode(', ', $user->roles);
$plain_message = <<<EOD
以下のユーザーがログインしました。
■ サイト: {$site_name}
■ URL: {$site_url}
■ ユーザー名: {$user_login}
■ 権限: {$roles}
■ ログイン日時: {$login_time}
■ IPアドレス: {$ip_address}
EOD;
$slack_message = "ユーザーログイン通知\n"
. "• サイト: {$site_name} ({$site_url})\n"
. "• ユーザー名: `{$user_login}`\n"
. "• 権限: `{$roles}`\n"
. "• ログイン日時: `{$login_time}`\n"
. "• IPアドレス: `{$ip_address}`";
$chatwork_message = "[info][title]ユーザーログイン通知[/title]"
. "■ サイト: {$site_name} ({$site_url})\n"
. "■ ユーザー名: {$user_login}\n"
. "■ 権限: {$roles}\n"
. "■ ログイン日時: {$login_time}\n"
. "■ IPアドレス: {$ip_address}"
. "[/info]";
if (get_option('mln_chatwork_enabled') === '1') {
$token = get_option('mln_chatwork_token');
$room = get_option('mln_chatwork_room_id');
if ($token && $room) {
wp_remote_post("https://api.chatwork.com/v2/rooms/{$room}/messages", [
'headers' => ['X-ChatWorkToken' => $token],
'body' => ['body' => $chatwork_message],
]);
}
}
if (get_option('mln_slack_enabled') === '1') {
$webhook = get_option('mln_slack_webhook_url');
if ($webhook) {
wp_remote_post($webhook, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode(['text' => $slack_message]),
]);
}
}
if (get_option('mln_email_enabled') === '1') {
$email_to = get_option('mln_email_to');
if ($email_to) {
$subject = "[{$site_name}] ログイン通知: {$user_login}";
wp_mail($email_to, $subject, $plain_message);
}
}
}
add_action('wp_login_failed', 'mln_notify_failed_login');
function mln_notify_failed_login($username) {
$site_name = get_bloginfo('name');
$ip = $_SERVER['REMOTE_ADDR'];
$time = current_time('mysql');
$site_url = home_url();
$plain = <<<EOD
[ログイン失敗通知]
■ サイト: {$site_name}
■ ユーザー名: {$username}
■ 時間: {$time}
■ IPアドレス: {$ip}
EOD;
$slack = "ログイン失敗通知\n"
. "• サイト: {$site_name} ({$site_url})\n"
. "• ユーザー名: `{$username}`\n"
. "• 時間: `{$time}`\n"
. "• IPアドレス: `{$ip}`";
$chatwork = "[info][title]ログイン失敗通知[/title]"
. "■ サイト: {$site_name} ({$site_url})\n"
. "■ ユーザー名: {$username}\n"
. "■ 時間: {$time}\n"
. "■ IPアドレス: {$ip}"
. "[/info]";
if (get_option('mln_chatwork_enabled') === '1') {
$token = get_option('mln_chatwork_token');
$room = get_option('mln_chatwork_room_id');
if ($token && $room) {
wp_remote_post("https://api.chatwork.com/v2/rooms/{$room}/messages", [
'headers' => ['X-ChatWorkToken' => $token],
'body' => ['body' => $chatwork],
]);
}
}
if (get_option('mln_slack_enabled') === '1') {
$webhook = get_option('mln_slack_webhook_url');
if ($webhook) {
wp_remote_post($webhook, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode(['text' => $slack]),
]);
}
}
if (get_option('mln_email_enabled') === '1') {
$to = get_option('mln_email_to');
$subject = "[{$site_name}] ログイン失敗: {$username}";
wp_mail($to, $subject, $plain);
}
}
includes/settings.php
<?php
add_action('admin_menu', function () {
add_menu_page(
'ログイン通知設定',
'ログイン通知',
'manage_options',
'multi-login-notifier',
'mln_settings_page',
'dashicons-admin-network',
83
);
});
add_action('admin_init', function () {
$options = [
'mln_chatwork_enabled', 'mln_chatwork_token', 'mln_chatwork_room_id',
'mln_slack_enabled', 'mln_slack_webhook_url',
'mln_email_enabled', 'mln_email_to',
'mln_allowed_roles', 'mln_excluded_users'
];
foreach ($options as $opt) {
register_setting('mln_settings_group', $opt);
}
});
function mln_settings_page() {
?>
<div class="wrap">
<h1>ログイン通知 設定</h1>
<form method="post" action="options.php">
<?php settings_fields('mln_settings_group'); ?>
<table class="form-table">
<tr><th colspan="2"><h2>Chatwork 通知</h2></th></tr>
<tr><th>有効化</th><td><input type="checkbox" name="mln_chatwork_enabled" value="1" <?php checked(get_option('mln_chatwork_enabled'), '1'); ?> /></td></tr>
<tr><th>APIトークン</th><td><input type="text" name="mln_chatwork_token" value="<?php echo esc_attr(get_option('mln_chatwork_token')); ?>" class="regular-text" /></td></tr>
<tr><th>ルームID</th><td><input type="text" name="mln_chatwork_room_id" value="<?php echo esc_attr(get_option('mln_chatwork_room_id')); ?>" class="regular-text" /></td></tr>
<tr><th colspan="2"><h2>Slack 通知</h2></th></tr>
<tr><th>有効化</th><td><input type="checkbox" name="mln_slack_enabled" value="1" <?php checked(get_option('mln_slack_enabled'), '1'); ?> /></td></tr>
<tr><th>Webhook URL</th><td><input type="text" name="mln_slack_webhook_url" value="<?php echo esc_attr(get_option('mln_slack_webhook_url')); ?>" class="regular-text" /></td></tr>
<tr><th colspan="2"><h2>メール通知</h2></th></tr>
<tr><th>有効化</th><td><input type="checkbox" name="mln_email_enabled" value="1" <?php checked(get_option('mln_email_enabled'), '1'); ?> /></td></tr>
<tr><th>送信先メールアドレス</th><td><input type="email" name="mln_email_to" value="<?php echo esc_attr(get_option('mln_email_to')); ?>" class="regular-text" /></td></tr>
<tr><th colspan="2"><h2>通知対象の制御</h2></th></tr>
<tr><th>対象ロール(カンマ区切り)</th><td><input type="text" name="mln_allowed_roles" value="<?php echo esc_attr(get_option('mln_allowed_roles')); ?>" class="regular-text" /></td></tr>
<tr><th>除外ユーザー名(カンマ区切り)</th><td><input type="text" name="mln_excluded_users" value="<?php echo esc_attr(get_option('mln_excluded_users')); ?>" class="regular-text" /></td></tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
おわりに
このプラグインは、サイトのログイン状況を得るのに最適な機能を提供します。
設定もシンプルで、使用現場に合わせて自由にカスタマイズも可能です。
コメント