You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel如何针对特定IP/域名跳过登录接口CSRF令牌验证

针对特定IP/域名排除CSRF校验的实现方法

Laravel默认VerifyCsrfToken中间件的$except属性仅支持匹配请求URI路径,不会自动识别请求来源IP、域名做放行判断,直接在数组内填写IP、完整URL地址不会生效。

正确实现需要重写中间件的判断逻辑,在原有URI匹配的基础上增加IP、来源域名的校验规则,具体操作如下:

  1. 打开app/Http/Middleware/VerifyCsrfToken.php文件,替换原有代码为以下逻辑:
namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
use Illuminate\Http\Request;

class VerifyCsrfToken extends Middleware
{
    /**
     * 无需CSRF校验的URI路径
     * @var array<int, string>
     */
    protected $except = [
        '/login',
    ];

    /**
     * 允许跳过CSRF校验的来源IP白名单,支持精确IP、CIDR网段
     * @var array<int, string>
     */
    protected $exceptIps = [
        '192.168.1.12',
        '10.0.0.0/8',
    ];

    /**
     * 允许跳过CSRF校验的来源域名白名单
     * @var array<int, string>
     */
    protected $exceptDomains = [
        'trusted.yourdomain.com',
    ];

    /**
     * 重写排除规则判断逻辑
     * @param Request $request
     * @return bool
     */
    protected function inExceptArray($request)
    {
        // 匹配IP白名单+指定路径
        if ($this->checkAllowedIp($request->ip()) && $request->is($this->except)) {
            return true;
        }

        // 匹配来源域名白名单+指定路径
        $origin = $request->headers->get('origin');
        if ($origin) {
            $originHost = parse_url($origin, PHP_URL_HOST);
            if (in_array($originHost, $this->exceptDomains) && $request->is($this->except)) {
                return true;
            }
        }

        // 保留框架原生URI匹配逻辑
        return parent::inExceptArray($request);
    }

    /**
     * 校验IP是否属于白名单范围
     * @param string $clientIp
     * @return bool
     */
    protected function checkAllowedIp(string $clientIp): bool
    {
        foreach ($this->exceptIps as $allowedIp) {
            // 精确IP匹配
            if ($clientIp === $allowedIp) {
                return true;
            }
            // CIDR网段匹配
            if (str_contains($allowedIp, '/')) {
                [$subnet, $mask] = explode('/', $allowedIp);
                if ((ip2long($clientIp) & ~((1 << (32 - $mask)) - 1)) == ip2long($subnet)) {
                    return true;
                }
            }
        }
        return false;
    }
}
  1. 根据实际业务需求修改$exceptIps、$exceptDomains数组内的IP、域名值即可。

注意事项

  • 禁止全局放开所有路径的CSRF校验,仅给必要的接口(如登录接口)配置白名单规则,避免引入安全漏洞
  • 如果服务前挂了CDN、Nginx反向代理,必须先在app/Http/Middleware/TrustProxies.php中配置可信代理IP,否则$request->ip()会获取到代理节点IP而非真实客户端IP,导致IP校验逻辑失效
  • 之前参考的方案返回419状态码,通常是两个原因:一是未同时匹配要放行的请求路径,二是代理场景下获取到的客户端IP不准确
  • 域名校验读取的是请求的Origin头,仅将完全可控的内部域名加入白名单,不要随意加入未知来源域名

内容的提问来源于stack exchange,提问作者Iqbal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:39:43