Php 仅当用户使用Laravel处于活动状态时登录
我目前正在开发我的Laravel应用程序,为了防止垃圾邮件,我决定只有活跃用户才能登录。 我目前正在使用Laravel的登录系统,就像在Laravel的官方网站教程中一样,以下是我的表单操作:Php 仅当用户使用Laravel处于活动状态时登录,php,laravel,laravel-5,login,account,Php,Laravel,Laravel 5,Login,Account,我目前正在开发我的Laravel应用程序,为了防止垃圾邮件,我决定只有活跃用户才能登录。 我目前正在使用Laravel的登录系统,就像在Laravel的官方网站教程中一样,以下是我的表单操作: <form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}"> 这工作完全好,但是我想检查用户的活动,如果不是活动的,它将被重定向到激活页面,否则它将登录。 有没有一个简
<form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}">
这工作完全好,但是我想检查用户的活动,如果不是活动的,它将被重定向到激活页面,否则它将登录。
有没有一个简单的方法可以做到这一点,或者我有义务做一个新的控制器,路由和更多的验证?多谢各位
编辑:忘记提到我的数据库中有一个“活动”列。Laravel 5.4/5.5
将默认的login()
函数放置在LoginController
中,以覆盖该函数:
公共函数登录(\illumb\Http\Request$Request){
$this->validateLogin($request);
//如果类正在使用ThrottlesLogins特性,我们可以自动进行节流
//此应用程序的登录尝试。我们将通过用户名和
//向此应用程序发出这些请求的客户端的IP地址。
如果($this->hastoomanyLogin尝试($request)){
$this->fireLockoutEvent($request);
返回$this->sendLockoutResponse($request);
}
//这一部分是唯一的变化
如果($this->guard()->validate($this->credentials($request))){
$user=$this->guard()->getlast();
//确保用户处于活动状态
如果($user->active&&$this->attemptLogin($request)){
//发送正常的成功登录响应
返回$this->sendLoginResponse($request);
}否则{
//增加失败的登录尝试并重定向回
//带有错误消息的登录表单。
$this->incrementLoginAttents($request);
返回重定向()
->back()
->withInput($request->only($this->username(),'memory'))
->withErrors(['active'=>“您必须处于活动状态才能登录。”]);
}
}
//如果登录尝试失败,我们将增加尝试次数
//登录并将用户重定向回登录表单。当然,当
//用户超过其最大尝试次数将被锁定。
$this->incrementLoginAttents($request);
返回$this->sendFailedLoginResponse($request);
}
与此问题的许多其他答案相比,建议以这种方式覆盖login()
方法,因为它允许您仍然使用Laravel 5.4+的许多更高级的身份验证功能,例如登录限制、多个身份验证保护驱动程序/提供程序,等,同时仍允许您设置自定义错误消息
拉威尔5.3 更改或覆盖
AuthController
中的postLogin()
函数,如下所示:
protected function getCredentials(Request $request) {
$request['active'] = TRUE;
return $request->only($this->loginUsername(), 'password', 'active');
}
class User extends Authenticatable {
...
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot() {
parent::boot();
static::addGlobalScope('scopeActive', function (Builder $builder) {
$builder->where('active', 1);
});
}
...
公共函数后登录(请求$Request)
{
$this->validate$请求[
'email'=>'必填项| email'、'password'=>'必填项',
]);
$credentials=$this->getCredentials($request);
//这一部分是唯一的变化
if(Auth::validate($credentials)){
$user=Auth::getLastAttempted();
如果($user->active){
Auth::login($user,$request->has('memory');
return redirect()->designed($this->redirectPath());
}否则{
return redirect($this->loginPath())//将其更改为重定向到其他位置
->withInput($request->only('email','memory'))
->威瑟罗([
“活动”=>“您必须处于活动状态才能登录。”
]);
}
}
返回重定向($this->loginPath())
->withInput($request->only('email','memory'))
->威瑟罗([
'email'=>this->getFailedLoginMessage(),
]);
}
此代码重定向回登录页面,并显示有关用户处于非活动状态的错误消息。如果您想重定向到身份验证页面,您可以更改我用注释标记的行
将此更改为重定向到别处
您不必重写整个函数。您只需更改AuthController中的验证器即可实现添加“exists:table,column”验证
假设您有一个包含电子邮件、密码和活动字段的用户表
'email' => 'exists:users,email,active,1'
或者,如果您使用的是软删除,这应该也可以
'email' => 'exists:users,email,deleted_at,NULL'
“电子邮件”=>“存在:用户、电子邮件、已删除位置、空”
您还可以在AuthController override method getCredentials中的此链接上签出验证规则,如下所示:
protected function getCredentials(Request $request) {
$request['active'] = TRUE;
return $request->only($this->loginUsername(), 'password', 'active');
}
class User extends Authenticatable {
...
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot() {
parent::boot();
static::addGlobalScope('scopeActive', function (Builder $builder) {
$builder->where('active', 1);
});
}
...
确保用户表上的列处于活动状态…将以下方法粘贴到
登录控制器中
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'exists:users,' . $this->username() . ',active,1',
'password' => 'required|string',
]);
}
最后两个逗号分隔的参数(active,1
)用作WHERE子句(WHERE active='1'
),也可以这样编写:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => Rule::exists('users')->where(function ($query) {
$query->where('active', 1);
}),
'password' => 'required|string'
]);
}
通常,验证方法仅检查是否填写了电子邮件和密码字段。通过上面的修改,我们要求在数据库行中找到一个给定的电子邮件地址,并且active
值设置为1
您还可以自定义消息:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'exists:users,' . $this->username() . ',active,1',
'password' => 'required|string',
], [
$this->username() . '.exists' => 'The selected email is invalid or the account has been disabled.'
]);
}
请注意,上述消息将在给定电子邮件地址不存在或帐户被禁用时显示。在Laravel 5.4中打开Auth/LoginController.php
protected function validator(array $data)
{
return Validator::make($data, [
'email' => 'required|email|max:255|exists:users,email,active,1',
'password' => 'required|confirmed'
]);
}
use Illuminate\Http\Request;
use App\User;
use Illuminate\Validation\ValidationException;
并添加此功能:
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
//return $request->only($this->username(), 'password');
return ['email' => $request->{$this->username()}, 'password' => $request->password, 'status' => 1];
}
你完了 如果有人来这里查找有关Laravel 5.4/5.5的信息,并且这允许仅针对此场景的自定义消息(而不是组合消息),以下是来自
覆盖“app/Http/Controllers/Auth/LoginController.php”文件中的“authenticated”方法:
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
if ($user->status_id == 2) { // or whatever status column name and value indicates a blocked user
$message = 'Some message about status';
// Log the user out.
$this->logout($request);
// Return them to the log in form.
return redirect()->back()
->withInput($request->only($this->username(), 'remember'))
->withErrors([
// This is where we are providing the error message.
$this->username() => $message,
]);
}
}
我检查用户是否通过LoginController中的overwrite sendLoginResponse函数激活
protected function sendLoginResponse(Request $request)
{
if($this->guard()->user()->active == 0){
$this->guard()->logout();
return redirect()->back()
->withInput($request->only($this->username(), 'remember'))
->withErrors(['active' => 'User in not activated.']);
}
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
如果有人在登录时使用ajax请求并想要定制消息,下面是我如何在登录控制器中实现这一点的
public function handle($request, Closure $next, ...$guards)
{
if(!$request->user()->active){
// either abort with simple 403 access denied page
// abort(403, "You don't have permissions to access this area");
// OR force Logout and redirect back to the login page
return redirect('login')->with($this->auth->logout());
}
$this->authenticate($request, $guards);
return $next($request);
}
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
class User extends Authenticatable {
...
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot() {
parent::boot();
static::addGlobalScope('scopeActive', function (Builder $builder) {
$builder->where('active', 1);
});
}
...
public function login(Request $request)
{
$user = User::where('username',$request->username)->first();
if( $user && !$user->active){
return redirect()->back()->with('error','the user has been desactivated');
}
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
// Get the user details from database and check if email is verified.
$user = User::where('username', '=', $request->input($this->username()))->first();
if ($user->email_verified_at == NULL) {
throw ValidationException::withMessages([$this->username() => __('auth.failed_login_missing_email_verification')]);
}
// Email is verified, validate input.
return $request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
use Illuminate\Http\Request;
use App\User;
use Illuminate\Validation\ValidationException;
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
// Get the user details from database and check if user is exist and active.
$user = User::where('email',$request->email)->first();
if( $user && !$user->activation){
throw ValidationException::withMessages([$this->username() => __('User has been desactivated.')]);
}
// Then, validate input.
return $request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
// ...
}
Auth::routes(['verify' => true]);
/**
* Custom credentials to validate the status of user.
*/
public function credentials(Request $request)
{
return [
'email' => $request->email,
'password' => $request->password,
'is_active' => '1'
];
}
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
public function login(Request $request){
$this->validateLogin($request);
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if($this->guard()->validate($this->credentials($request))) {
// Check if user is active, else return error message
if(Auth::attempt(['email' => $request->email, 'password' => $request->password, 'status' => 'A'])) {
return redirect()->intended('dashboard');
} else {
// This will return the message required as desired
return $this->inactiveCredential($request);
}
} else {
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
}
// Error massage for inactive credential
private function inactiveCredential(Request $request){
throw ValidationException::withMessages([
// auth.not-active can be added in resources/lang/en/auth.php
$this->username() => [trans('auth.not-active')],
]);
}
'not-active' => 'This account is already deleted. Contact administrator to revoke this account',
protected function sendLoginResponse(Request $request) {
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
$user = $this->guard()->user();
if($user->is_active) {
return $request->wantsJson() ? new JsonResponse([], 204) : redirect()->intended($this->redirectPath());
} else {
$request->session()->flush();
return redirect()->route('login')->with('error', 'This account is not activated. Please contact the administrator.');
}
}
class ForgotPasswordController extends Controller
{
//...
protected function credentials(Request $request)
{
// is_active field in user model must be true.
$request->merge(['is_active' => true]);
return $request->only('email', 'active');
}
}
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
//ADD THIS SECTION ONLY
//SECTION STARTS
// CHECK IF USER EXISTS IN OUR USER TABLE.
if ($this->guard()->validate($this->credentials($request))) {
//IF USER EXISTS, FIND USER USING EMAIL FROM REQUEST
$user = User::where('email', $request->email)->first();
//CHECK STATUS OF USER (HERE, 1 = ACTIVE & 0 = INACTIVE)
if ($user->status===0) {
//THROW ERROR WITH CUSTOM MESSAGE
throw ValidationException::withMessages([$this->username() => __('User account has been deactivated.')]);
}
}
//SECTION ENDS
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}