无聊的功能之一,有需要的可以尝试一下,豆包帮忙写的,登录会触发机器人推送消息。

1、增加注册事件与监听器

路径/app/Providers/EventServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Registered; // 补回原有事件
use Illuminate\Auth\Listeners\SendEmailVerificationNotification; // 补回原有监听器
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Listeners\SendLoginNotification; // 登录提醒监听器

class EventServiceProvider extends ServiceProvider
{
    /**
     * 应用程序的事件监听器映射
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        // 原有:用户注册事件(补回)
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        // 新增:登录成功提醒(保留)
        Login::class => [
            SendLoginNotification::class,
        ],
    ];

    public function boot(): void
    {
        //
    }

    public function shouldDiscoverEvents(): bool
    {
        return false;
    }
}

2、增加文件SendLoginNotification.php
编写监听器逻辑
路径/app/Listeners/SendLoginNotification.php

<?php

namespace App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;

class SendLoginNotification
{
    protected $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

public function handle(Login $event)
{
    $user = $event->user;
    
    try {
        // 关键修改:将 username 改为 name(适配兰空图床字段)
        $username = '未知用户';
        if (isset($user->name) && !empty($user->name)) {
            $username = $user->name;
        }
        
        $email = '未知邮箱';
        if (isset($user->email) && !empty($user->email)) {
            $email = $user->email;
        }
        
        // 已删除 $device 相关定义和赋值
        
        $loginData = array(
            'username' => $username, // 这里键名不影响,值已正确获取
            'email' => $email,
            'ip' => $this->request->ip(),
            'ip_location' => $this->getIpLocation($this->request->ip()),
            // 已删除 'device' => $device 字段
            'time' => Carbon::now()->format('Y-m-d H:i:s'),
        );

        $this->sendDingTalkNotificationWithSign($loginData);

    } catch (\Exception $e) {
        $errUser = '未知用户';
        if (isset($user->name) && !empty($user->name)) {
            $errUser = $user->name;
        }
        Log::error("钉钉登录提醒执行异常:" . $e->getMessage() . ",用户:" . $errUser);
    }
}

    /**
     * 钉钉加签提醒(兼容所有PHP版本)
     */
    private function sendDingTalkNotificationWithSign($loginData)
    {
        try {
            // ========== 替换为你的钉钉信息 ==========
            $dingWebhook = 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxx';
            $dingSecret = 'SECxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
            // ======================================

            // 生成加签参数(兼容写法)
            $timestamp = time() * 1000;
            $signStr = $timestamp . "\n" . $dingSecret;
            $sign = base64_encode(hash_hmac('sha256', $signStr, $dingSecret, true));
            $sign = urlencode($sign);

            // 拼接链接
            $finalDingWebhook = $dingWebhook . "&timestamp=" . $timestamp . "&sign=" . $sign;

            // 构造钉钉消息(用array而非短数组,兼容低版本)
            $dingMessage = array(
                'msgtype' => 'text',
                'text' => array(
                    'content' => "【兰空图床登录提醒】\n" .
                        "——————————————\n" .
                        "用户名:" . $loginData['username'] . "\n" .
                        "登录IP:" . $loginData['ip'] . " (" . $loginData['ip_location'] . ")\n" .
                        // 已删除 登录设备 展示行
                        "登录时间:" . $loginData['time'] . "\n" .
                        "——————————————"
                )
            );

            // 发送请求(兼容写法)
            $response = Http::withHeaders(array('Content-Type' => 'application/json'))
                ->post($finalDingWebhook, $dingMessage);

            // 验证响应(移除===,用==兼容)
            if ($response->successful() && $response->json('errcode') == 0) {
                Log::info("钉钉提醒发送成功,用户:" . $loginData['username']);
            } else {
                Log::error("钉钉提醒失败,响应:" . $response->body());
            }
        } catch (\Exception $e) {
            Log::error("钉钉加签发送异常:" . $e->getMessage());
        }
    }

    /**
     * IP归属地查询(兼容所有PHP版本)
     */
    private function getIpLocation($ip)
    {
        if (in_array($ip, array('127.0.0.1', '::1'))) {
            return '本地网络';
        }

        try {
            $response = Http::timeout(3)->get("http://ip-api.com/json/" . $ip . "?lang=zh-CN");
            $data = $response->json();
            if ($data['status'] == 'success') {
                return $data['country'] . '-' . $data['regionName'] . '-' . $data['city'];
            } else {
                return '未知地区';
            }
        } catch (\Exception $e) {
            Log::warning("IP归属地查询失败:" . $e->getMessage());
            return '未知地区';
        }
    }
}

3、创建钉钉机器人获取地址和加签秘钥,配置到代码里面

  log记录在/storage/logs里面

给兰空图床增加一个机器人登录提醒