Laravel - 使用用户名、电子邮件或电话登录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47537191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel - Login with username, email or phone
提问by Srikanth Gopi
I have implemented login with username or email in my existing project and works fine. I want to extend it to login with username, email or phone. I want a user to login with either username, email or phone number and password.
我已经在我现有的项目中使用用户名或电子邮件实现了登录并且工作正常。我想将其扩展为使用用户名、电子邮件或电话登录。我希望用户使用用户名、电子邮件或电话号码和密码登录。
Here is my code App\Http\Controllers\Auth\LoginController
这是我的代码 App\Http\Controllers\Auth\LoginController
<?php
namespace App\Http\Controllers\Auth;
use Socialite;
use Illuminate\Http\Request;
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');
}
/**
* Redirect the user to the GitHub authentication page.
*
* @return \Illuminate\Http\Response
*/
public function redirectToProvider($social)
{
return Socialite::driver($social)->redirect();
}
/**
* Obtain the user information from GitHub.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback($social)
{
$user = Socialite::driver($social)->user();
// $user->token;
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
$field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL)
? $this->username()
: 'username';
return [
$field => $request->get($this->username()),
'password' => $request->password,
];
}
}
App\Http\Controllers\Auth\RegisterController
App\Http\Controllers\Auth\RegisterController
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'username' => 'required|string|max:20|unique:users',
'phone' => 'required|string|max:20|unique:users',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'gender' => 'required|bool',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
if($data['gender'])
{
$avatar = 'default/avatars/male.png';
}
else
{
$avatar = 'default/avatars/female.png';
}
return User::create([
'name' => $data['name'],
'gender' => $data['gender'],
'username' => $data['username'],
'phone' => $data['phone'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'slug' => str_slug($data['username']),
'avatar' => $avatar,
]);
}
}
Registration works fine and im able to store the user phone to the users table. I have changed the input type for email to text on views/auth/login.php and im able to login with either username or email.
注册工作正常,我能够将用户电话存储到用户表中。我已将电子邮件的输入类型更改为 views/auth/login.php 上的文本,并且我可以使用用户名或电子邮件登录。
When i change the username to phone in LoginController im unable to login with phone as it says Method [phone] does not exist on [App\Http\Controllers\Auth\LoginController].
当我在 LoginController 中将用户名更改为电话时,我无法使用电话登录,因为它说 [App\Http\Controllers\Auth\LoginController] 上不存在方法 [电话]。
When i add a method
当我添加一个方法时
/**
* Create a new controller instance.
*
* @return void
*/
public function phone()
{
return 'phone';
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
$field = filter_var($request->get($this->phone()), FILTER_VALIDATE_EMAIL)
? $this->phone()
: 'phone';
return [
$field => $request->get($this->phone()),
'password' => $request->password,
];
}
It doesn't let me login with phone. Error These credentials do not match our records. Also Tried
它不允许我用手机登录。错误 这些凭据与我们的记录不匹配。也试过
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
if(is_numeric($request->get('email'))){
return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
}
return $request->only($this->username(), 'password');
}
I'm able to login with phone or email now but not with username How to achieve login with username, email or phone
我现在可以使用电话或电子邮件登录,但不能使用用户名 如何使用用户名、电子邮件或电话登录
回答by Srikanth Gopi
This code works. Hope it helps someone.
此代码有效。希望它可以帮助某人。
protected function credentials(Request $request)
{
if(is_numeric($request->get('email'))){
return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
}
elseif (filter_var($request->get('email'), FILTER_VALIDATE_EMAIL)) {
return ['email' => $request->get('email'), 'password'=>$request->get('password')];
}
return ['username' => $request->get('email'), 'password'=>$request->get('password')];
}
If is numeric, login with number. If is email, login with email address. Else try username
如果是数字,用数字登录。如果是电子邮件,请使用电子邮件地址登录。否则尝试用户名
Final LoginController looks like this
最终的 LoginController 看起来像这样
<?php
namespace App\Http\Controllers\Auth;
use Socialite;
use Illuminate\Http\Request;
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');
}
/**
* Redirect the user to the GitHub authentication page.
*
* @return \Illuminate\Http\Response
*/
public function redirectToProvider($social)
{
return Socialite::driver($social)->redirect();
}
/**
* Obtain the user information from GitHub.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback($social)
{
$user = Socialite::driver($social)->user();
// $user->token;
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
if(is_numeric($request->get('email'))){
return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
}
elseif (filter_var($request->get('email'), FILTER_VALIDATE_EMAIL)) {
return ['email' => $request->get('email'), 'password'=>$request->get('password')];
}
return ['username' => $request->get('email'), 'password'=>$request->get('password')];
}
}
回答by Tobias dsn
This code works for Laravel 7
此代码适用于 Laravel 7
Step 1 -- Add method username in class LoginController
步骤 1 -- 在类 LoginController 中添加方法 username
public function username()
{
$login = request()->input('username');
if(is_numeric($login)){
$field = 'phone';
} elseif (filter_var($login, FILTER_VALIDATE_EMAIL)) {
$field = 'email';
} else {
$field = 'username';
}
request()->merge([$field => $login]);
return $field;
}
Step 2 -- Add method sendFailedLoginResponse in class LoginController
步骤 2 -- 在类 LoginController 中添加方法 sendFailedLoginResponse
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
'username' => [trans('auth.failed')],
]);
}
Final LoginController looks like this
最终的 LoginController 看起来像这样
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
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 = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
'username' => [trans('auth.failed')],
]);
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
$login = request()->input('username');
if(is_numeric($login)){
$field = 'phone';
} elseif (filter_var($login, FILTER_VALIDATE_EMAIL)) {
$field = 'email';
} else {
$field = 'username';
}
request()->merge([$field => $login]);
return $field;
}
}
Step 3 -- Edit view login.blade.php -> login form
第 3 步——编辑视图 login.blade.php -> 登录表单
- the name from name="email" to name="username"
- change error message from email to username
- 从 name="email" 到 name="username" 的名称
- 将错误消息从电子邮件更改为用户名
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="username" class="col-md-4 col-form-label text-md-right">{{ __('Username/Email/Phone') }}</label>
<div class="col-md-6">
<input id="username" type="text" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autofocus>
@error('username')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection