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

Laravel如何校验Gmail存在以规避`.`、`+`字符导致的重复注册问题

基于Laravel实现防Gmail别名重复的邮箱存在性验证

核心实现思路

Gmail 别名的核心特征是仅对@gmail.com和@googlemail.com后缀的邮箱生效:用户名中.会被完全忽略,+之后的所有后缀内容会被自动截断。我们只需要提前对输入邮箱做标准化归一处理,再用归一化后的结果做存在性校验即可,同时要注意不要对其他邮箱服务商的地址做额外处理,避免误伤正常规则。


具体实现步骤

1. 编写邮箱标准化辅助函数

可以在项目中新增通用辅助方法,用于处理邮箱归一化:

if (! function_exists('normalize_email')) {
    function normalize_email(string $email): string
    {
        // 统一转为小写,避免大小写差异导致的重复
        $email = strtolower($email);
        // 拆分用户名和域名
        [$username, $domain] = explode('@', $email, 2);

        // 仅对Gmail公开域名做特殊处理
        if (in_array($domain, ['gmail.com', 'googlemail.com'])) {
            // 移除+及之后的所有内容
            $username = strstr($username, '+', true) ?: $username;
            // 移除用户名中所有的.
            $username = str_replace('.', '', $username);
        }

        return sprintf('%s@%s', $username, $domain);
    }
}

2. 新增标准化邮箱存储字段

需要在用户表中新增normalized_email字段用于唯一校验,原始邮箱字段保留用于给用户发送邮件等业务场景,避免篡改用户提交的原始邮箱。
迁移文件示例:

Schema::table('users', function (Blueprint $table) {
    $table->string('normalized_email')->unique()->after('email');
});

用户注册写入数据时,同步把标准化后的邮箱存入该字段。

3. 替换原有exists验证规则

不再直接用原始邮箱做exists校验,改为用标准化后的邮箱查询normalized_email字段:

// 注册场景的验证规则示例
$validated = $request->validate([
    'email' => [
        'required',
        'email',
        // 自定义校验逻辑,替换原有exists:users,email
        function ($attribute, $value, $fail) {
            $normalizedEmail = normalize_email($value);
            if (\App\Models\User::where('normalized_email', $normalizedEmail)->exists()) {
                $fail('该邮箱地址已被注册');
            }
        },
    ],
    // 其他验证规则...
]);

扩展说明

如果需要支持企业版G Suite的自定义域名,可自行在辅助函数的Gmail域名判断列表中添加对应域名即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:48:02