在 Laravel 中实现同时使用邮箱和手机号登录,需要自定义认证逻辑。以下是实现步骤:
1. 数据库准备
确保 users
表包含 email
和 phone
字段,并添加唯一索引。
迁移文件示例:
// database/migrations/xxxx_add_phone_to_users_table.php
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->unique()->nullable();
});
}
2. 修改用户模型
在 User
模型中添加 phone
到 fillable
属性。
app/Models/User.php
protected $fillable = [
'name',
'email',
'phone',
'password',
];
3. 调整登录视图
将输入字段从 email
改为 login
,允许用户输入邮箱或手机号。
resources/views/auth/login.blade.php
<input
id="login"
type="text"
name="login"
value="{{ old('login') }}"
required
autofocus
placeholder="邮箱或手机号"
>
4. 自定义登录凭证逻辑
在 LoginController
中覆盖 credentials
方法,动态判断登录字段。
app/Http/Controllers/Auth/LoginController.php
use Illuminate\Http\Request;
protected function credentials(Request $request)
{
$login = $request->input('login');
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
return [
$field => $login,
'password' => $request->input('password'),
];
}
5. 修改验证规则
调整登录请求的验证规则,允许 login
字段。
app/Http/Requests/LoginRequest.php(如果使用 FormRequest)
public function rules()
{
return [
'login' => 'required|string',
'password' => 'required|string',
];
}
或直接在控制器中验证:
$request->validate([
'login' => 'required|string',
'password' => 'required|string',
]);
6. 处理手机号格式(可选)
如果手机号需要特定格式(如包含国家码),在查询前格式化解:
protected function credentials(Request $request)
{
$login = $request->input('login');
if (filter_var($login, FILTER_VALIDATE_EMAIL)) {
$field = 'email';
} else {
$field = 'phone';
$login = $this->formatPhone($login); // 自定义格式化方法
}
return [
$field => $login,
'password' => $request->input('password'),
];
}
private function formatPhone($phone)
{
// 示例:移除非数字字符并添加国家码
return '+86' . preg_replace('/\D/', '', $phone);
}
7. 错误消息本地化(可选)
在 resources/lang/en/auth.php 中调整错误提示:
'failed' => '邮箱或手机号与密码不匹配。',
8. 测试登录场景
确保以下情况正常工作:
- 使用邮箱 + 密码登录
- 使用手机号 + 密码登录
- 错误邮箱/手机号提示
- 密码错误提示
注意事项:
- 确保
email
和phone
字段在数据库中唯一。 - 如果允许
phone
为空,需在注册逻辑中处理。 - 使用手机号时,建议在前端添加格式验证(如输入掩码)。
通过以上步骤,即可在 Laravel 中实现邮箱和手机号双方式登录。