本文目录导读:

- 使用预定义 IP 白名单(最简单)
- 使用中间件方式(推荐)
- 使用 Laravel 的
php artisan down命令 - 在
.env文件中配置 - 创建维护模式视图
- 高级方案:使用 Redis 动态管理 IP
- 推荐使用方案
在 Laravel 中设置维护模式并排除特定 IP,有多种方法,以下是详细的解决方案:
使用预定义 IP 白名单(最简单)
在 bootstrap/app.php 中配置:
<?php
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
// 配置维护模式排除的 IP
$app->configure('app');
return $app->createApplication(function ($app) {
// 在维护模式下允许访问的 IP 列表
$app->make(Illuminate\Contracts\Http\Kernel::class)
->setMaintenanceModeHandler(function () {
// 定义允许访问的 IP
$allowedIPs = [
'127.0.0.1', // 本地
'192.168.1.100', // 办公室 IP
'103.21.58.61', // 特定 IP
];
$currentIP = request()->ip();
if (in_array($currentIP, $allowedIPs)) {
return response()->make('', 200);
}
// 返回维护模式页面
return response()->make(
view('errors.maintenance'),
503,
['Retry-After' => 3600]
);
});
});
使用中间件方式(推荐)
创建自定义维护模式中间件
php artisan make:middleware CheckMaintenanceMode
中间件代码
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckMaintenanceMode extends Middleware
{
/**
* 允许访问的 IP 地址列表
*/
protected $allowedIPs = [
'127.0.0.1',
'192.168.1.0/24', // 支持 CIDR 格式
'103.21.58.61',
];
/**
* 处理请求
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 如果应用处于维护模式且当前 IP 不在白名单中
if ($this->app->isDownForMaintenance() &&
!$this->isAllowedIP($request->ip())) {
return response()->json([
'message' => '系统正在维护中,请稍后再试',
'code' => 503
], 503);
}
return $next($request);
}
/**
* 检查 IP 是否在允许列表中
*/
protected function isAllowedIP($ip)
{
foreach ($this->allowedIPs as $allowedIP) {
if ($this->ipMatches($ip, $allowedIP)) {
return true;
}
}
return false;
}
/**
* 检查 IP 匹配(支持通配符和 CIDR)
*/
protected function ipMatches($ip, $allowedIP)
{
// 完全匹配
if ($ip === $allowedIP) {
return true;
}
// 支持 * 通配符,如 192.168.*.*
if (strpos($allowedIP, '*') !== false) {
$pattern = str_replace('*', '(.*)', preg_quote($allowedIP, '/'));
return (bool) preg_match("/^{$pattern}$/", $ip);
}
// 支持 CIDR 格式,如 192.168.1.0/24
if (strpos($allowedIP, '/') !== false) {
return $this->ipInCidr($ip, $allowedIP);
}
return false;
}
/**
* 检查 IP 是否在 CIDR 范围内
*/
protected function ipInCidr($ip, $cidr)
{
list($subnet, $bits) = explode('/', $cidr);
if ($bits == 0) {
$bits = 32;
}
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask;
return ($ip & $mask) == $subnet;
}
}
注册中间件
在 app/Http/Kernel.php 中注册:
protected $middleware = [
// ...
\App\Http\Middleware\CheckMaintenanceMode::class,
];
使用 Laravel 的 php artisan down 命令
# 启用维护模式,排除特定 IP php artisan down --allow=127.0.0.1 --allow=192.168.1.0/24 # 或者使用配置文件 php artisan down --allow=103.21.58.61
查看当前维护模式状态
php artisan down --status
在 .env 文件中配置
在 .env 文件中添加:
MAINTENANCE_ALLOWED_IPS=127.0.0.1,192.168.1.100,103.21.58.61
然后在代码中使用:
$allowedIPs = explode(',', env('MAINTENANCE_ALLOWED_IPS', ''));
protected function setUpMaintenanceMode()
{
if ($this->app->isDownForMaintenance()) {
$allowedIPs = explode(',', env('MAINTENANCE_ALLOWED_IPS', ''));
if (!in_array(request()->ip(), $allowedIPs)) {
abort(503, '系统维护中');
}
}
}
创建维护模式视图
创建 resources/views/errors/maintenance.blade.php:
<!DOCTYPE html>
<html>
<head>系统维护中</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
.maintenance-box {
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
max-width: 600px;
margin: 100px auto;
}
h1 {
color: #333;
margin-bottom: 20px;
}
p {
color: #666;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="maintenance-box">
<h1>🔧 系统维护中</h1>
<p>系统正在进行维护升级,预计将在 <strong>30分钟</strong> 内完成。</p>
<p>给您带来的不便,敬请谅解!</p>
</div>
</body>
</html>
高级方案:使用 Redis 动态管理 IP
<?php
namespace App\Services;
use Illuminate\Support\Facades\Redis;
class MaintenanceModeManager
{
protected $redis;
public function __construct()
{
$this->redis = Redis::connection();
}
public function addAllowedIP($ip)
{
$this->redis->sadd('maintenance:allowed_ips', $ip);
}
public function removeAllowedIP($ip)
{
$this->redis->srem('maintenance:allowed_ips', $ip);
}
public function isAllowed($ip)
{
return $this->redis->sismember('maintenance:allowed_ips', $ip);
}
public function getAllowedIPs()
{
return $this->redis->smembers('maintenance:allowed_ips');
}
}
推荐使用方案
对于大多数项目,推荐使用方案 2(中间件方式),因为:
- 代码清晰,易于维护
- 支持复杂的 IP 匹配逻辑(通配符、CIDR)
- 可以自定义响应格式
- 方便切换功能
记得在生产环境测试时,确保你当前的 IP 在白名单中,否则可能会被锁在外面!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播