Files
chatroom/app/Http/Controllers/Admin/AdminAuthController.php

148 lines
4.7 KiB
PHP
Raw Normal View History

2026-04-14 13:43:16 +08:00
<?php
/**
* 文件功能:后台隐藏登录控制器
*
* 仅提供站长独立登录入口,登录成功后直接进入后台控制台,
* 不经过聊天室首页与“登录即注册”流程。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\AdminLoginRequest;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
* 类功能:处理站长隐藏登录页展示与登录提交。
*/
class AdminAuthController extends Controller
{
/**
* 隐藏登录入口后缀。
*/
private const LOGIN_SUFFIX = 'lkddi';
/**
* 站长账号固定主键。
*/
private const SITE_OWNER_ID = 1;
/**
* 显示站长隐藏登录页面。
*/
public function create(Request $request): View|RedirectResponse
{
// 已通过隐藏入口登录的站长再次访问时,直接回后台首页
if (Auth::id() === self::SITE_OWNER_ID && $request->session()->get('admin_login_via_hidden')) {
return redirect()->route('admin.dashboard');
}
return view('admin.auth.login', [
'loginSuffix' => self::LOGIN_SUFFIX,
]);
}
/**
* 处理站长隐藏登录请求。
*/
public function store(AdminLoginRequest $request): RedirectResponse
{
$validated = $request->validated();
$siteOwner = User::query()->find(self::SITE_OWNER_ID);
// 只有 id=1 的站长账号允许通过该入口进入后台
if (! $siteOwner || $siteOwner->username !== $validated['username']) {
return back()
->withInput($request->safe()->only(['username']))
->withErrors(['username' => '该入口仅限站长账号使用。']);
}
if (! $this->passwordMatches($siteOwner, $validated['password'])) {
return back()
->withInput($request->safe()->only(['username']))
->withErrors(['password' => '账号或密码错误。']);
}
// 若当前已有其他账号占用会话,先退出后再切换为站长会话
if (Auth::check() && Auth::id() !== $siteOwner->id) {
Auth::logout();
}
Auth::login($siteOwner);
$request->session()->regenerate();
$request->session()->put('admin_login_via_hidden', true);
// 复用主登录的会话登记逻辑,保证后台入口也会更新登录痕迹
$this->recordAdminLogin($siteOwner, (string) $request->ip());
return redirect()->route('admin.dashboard')->with('success', '站长后台登录成功。');
}
/**
* 校验站长密码,兼容旧库 MD5 并自动升级为 bcrypt。
*/
private function passwordMatches(User $siteOwner, string $plainPassword): bool
{
try {
if (Hash::check($plainPassword, $siteOwner->password)) {
return true;
}
} catch (\RuntimeException $exception) {
// 旧库非 bcrypt 密码会在这里抛异常,后续继续走 MD5 兼容逻辑
}
if (md5($plainPassword) !== $siteOwner->password) {
return false;
}
// 兼容老密码登录成功后,立即升级为 Laravel 默认哈希
$siteOwner->forceFill([
'password' => Hash::make($plainPassword),
])->save();
return true;
}
/**
* 记录站长通过隐藏入口登录后的访问痕迹。
*/
private function recordAdminLogin(User $siteOwner, string $ip): void
{
// 登录成功后补齐访问次数、IP 与时间,保持与前台登录统计一致
$siteOwner->increment('visit_num');
$siteOwner->update([
'previous_ip' => $siteOwner->last_ip,
'last_ip' => $ip,
'log_time' => now(),
'in_time' => now(),
]);
\App\Models\IpLog::create([
'ip' => $ip,
'sdate' => now(),
'uuname' => $siteOwner->username,
]);
try {
$wechatService = new \App\Services\WechatBot\WechatNotificationService;
$wechatService->notifyAdminOnline($siteOwner);
$wechatService->notifyFriendsOnline($siteOwner);
$wechatService->notifySpouseOnline($siteOwner);
} catch (\Exception $exception) {
// 机器人通知异常不影响站长进入后台,但需要落日志便于排查
Log::error('Hidden admin login notification failed', ['error' => $exception->getMessage()]);
}
}
}