问题
I'm using Laravel 6 and want user can alternatively login by email or mobile.
My attempts so far:
- Migration is working fine.
- Registration is working fine
Login works fine one at a time either email or mobile with below changes in loginController.php.
public function username()
{
return 'mobile'; // or email
}
and also login.blade.php for HTML forms from email to mobile.
I tried to validate both email and phone by @error directive, like @error('email') || @error('mobile') is-invalid @enderror but no action after submit. below is the example
<input id="user_login" type="text" class="form-control @error('email') || @error('mobile') is-invalid @enderror" name="user_login" value="{{ old('user_login') }}" required autocomplete="user_login" autofocus>
@error('user_login')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
Your help will be appreciated.
回答1:
change User migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->string('username')->unique()->nullable();
$table->string('mobile_number')->unique()->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
change User model:
protected $fillable = [
'name', 'email', 'password', 'mobile_number'
];
in app\Http\Controllers\Auth\RegisterController.php
change:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'mobile_number' => $data['mobile_number'],
'password' => Hash::make($data['password']),
]);
}
then change your register and login views and add a field to get mobile_number
回答2:
The provided blade template contains incorrect blade syntax that gets transformed to invalid php(the ||
is converted to plain text instead of the OR
operation).
Checkout the resulting php below:
This can be fixed by using the @error
and enderror
twice:
<form action="{{ route('test.store') }}" method="post">
<input id="user_login" type="text" class="form-control @error('email') is-invalid @enderror @error('mobile') is-invalid @enderror" name="user_login" value="{{ old('user_login') }}" required autocomplete="user_login" autofocus>
@error('user_login')
To add an additional field for authenticating the following can be used:
resources/auth/login.blade.php
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="phone" class="col-md-4 col-form-label text-md-right">{{ __('Phone') }}</label>
<div class="col-md-6">
<input id="phone" type="text" class="form-control @error('phone') is-invalid @enderror" name="email" value="{{ old('phone') }}" required autocomplete="email" autofocus>
@error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
app/Http/Auth/LoginController.php
Overriding the username()
method to use phone if provided and email as fallback.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return request()->has('phone') ? 'phone' : 'email';
}
}
or with a single field:
<div class="form-group row">
<label for="user_identifier" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address/Phone') }}</label>
<div class="col-md-6">
<input id="user_identifier" type="text" class="form-control @error('user_identifier') is-invalid @enderror" name="user_identifier" value="{{ old('user_identifier') }}" autofocus>
@error('user_identifier')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
and the associated LoginController
method:
public function username()
{
$identifier = request()->get('user_identifier');
if(filter_var($identifier, FILTER_VALIDATE_EMAIL)){
return 'email';
}
return 'phone';
}
来源:https://stackoverflow.com/questions/59908085/laravel-6-login-with-phone-or-email