Php 如果用户的帐户未激活,则将其重定向到一个页面

Php 如果用户的帐户未激活,则将其重定向到一个页面,php,laravel,Php,Laravel,注册后,用户状态默认设置为0,表示未激活。然后管理员需要批准(激活)他的帐户,然后他就可以打开所有其他路线。 我怎样才能在拉威尔做到这一点?现在我使用中间件: public function handle($request, Closure $next) { if (Auth::user()->userActive == 1) { return $next($request); } else { ret

注册后,用户状态默认设置为0,表示未激活。然后管理员需要批准(激活)他的帐户,然后他就可以打开所有其他路线。 我怎样才能在拉威尔做到这一点?现在我使用中间件:

public function handle($request, Closure $next)
    {
        if (Auth::user()->userActive == 1) {
            return $next($request);
        } else {
            return redirect('userNotActive');
        }
    }
我将其添加到route中:

Route::get('home', 'HomeController@index')->middleware('active');
Route::get('search', 'SearchController@searchFilter')->middleware('active');
Route::get('user/{id}', 'UserController@show')->middleware('active');

但是使用这个,我需要手动将中间件添加到所有路由中。是否有一种方法可以在登录后自动对所有路线有效?这是可能的。只需覆盖登录控制器中的laravel默认登录方法。下面是我的一个laravel项目的工作代码。不需要中间件

class LoginController {

    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 ($this->hasTooManyLoginAttempts($request)) {
                $this->fireLockoutEvent($request);

                return $this->sendLockoutResponse($request);
            }
            $credentials =['email'=>$request->email, 'password'=>$request->password];
            if($this->guard()->attempt($credentials,$request->has('remember'))){
                if(auth()->user()->active !=1){ //Account has not being activated!
                    $this->logout($request);
                    return back()
                        ->withInput()
                        ->withErrors(['email'=>'Your account is inactive. Click on the activation link sent to your account  to activate it']);

                }
                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);
        }

}

我几乎不建议您使用Route::group like

Route::group( ['middleware' => 'active'], function(){
    Route::get('home', 'HomeController@index');
    Route::get('search', 'SearchController@searchFilter');
    Route::get('user/{id}', 'UserController@show');
});

因此,您需要做的就是添加所有需要检查用户是否在该组中处于活动状态的页面。

有很多方法可以做到这一点。您可以按中间件创建中间件和分组路由,您可以按角色添加角色和允许,您可以验证输入,所有这些都取决于您希望如何组织或设计项目。我通常会根据自己的需要创建中间件,以及表单请求

我可能会在登录方法上实现@Samuel James answer,对于所有其他端点,使用下面的表单请求。 表单请求类似于:

创建一个formrequest

php artisan make:request LoginAccess
有了这个LoginAccess文件,我就有了一套规则和授权(认为用户模型与用于Auth的用户模型相同)

在您的控制器中,您可以使用LoginAccess作为您需要的任何方法的验证

public function SomeMethodThatNeedsUserLoggedInAndValidated(LoginAccess $request)
{
}

在注册方法中,添加此行以直接登录用户:

if (Auth::attempt(['email' => $email, 'password' => $password])) {
        // might need to add this too:
        Auth::user()->userActive = 1;

        // Authentication passed... user is logged in and active
        // @TODO : return redirect to your login start page or whatever you want to handle after login
}
您的中间件需要更改为:(由SO user@Demonyowh建议)。这是最好的做法,更易于使用

Route::group( ['middleware' => 'active'], function(){
    Route::get('home', 'HomeController@index');
    Route::get('search', 'SearchController@searchFilter');
    Route::get('user/{id}', 'UserController@show');
});

现在,当您使用register方法登录用户时,用户还可以访问中间件
active

中的所有路由。我是Laravel的新手,这也是针对新来者的。很长一段时间的人都可以随意告诉我为什么这是一种糟糕的做法,因为我真的不知道还有什么更好的做法

截至2019年8月24日,使用Laravel 5.8,这是我个人的实现

作出的假设:

  • 您开始使用Artisan Make:Auth
  • 您已将“活动”作为bool(tinyInt)添加到用户表中,并更新了相关模型等
  • 当“active”=0时,您试图阻止用户访问您的应用程序
  • 如果是这种情况,您可以让LoginController单独使用

    而是打开“illumb/Auth/Middleware/Authenticate.php”,并将handle()方法替换为:

    public function handle($request, Closure $next, ...$guards)
        {
            if(!$request->user()->active){
                // you can change 'login' to whatever you need
                return redirect('login')->with($this->auth->logout());
            }
    
            $this->authenticate($request, $guards);
            return $next($request);
        }
    
    注意:Auth::logout()在这里不起作用,但它已经通过文件顶部的构造函数拉入

    public function __construct(Auth $auth)
        {
            $this->auth = $auth;
        }
    
    因此,您只需使用$this->auth->logout();相反

    考虑一下——您可以很容易地将“活动”替换为几乎任何标准,并以相同的方式更新此中间件


    希望这有帮助

    将该条件添加到auth控制器?为什么不使用Route::group?但是使用该条件,我会得到一个错误
    尝试获取
    auth::user()->userActive==1的非对象属性
    ,因为用户未登录…所有路由都需要身份验证,那么为什么会出现这样的错误。。尝试获取非对象的属性意味着。。经过身份验证的用户没有userActive字段。。仅此而已..我如何排除登录路径?将其置于具有活动中间件的route::group之外这对我不起作用,因为我希望该用户登录并停留在
    userNotActive
    blade上,除非他被激活。如果他试图在url中手动插入路由,例如
    localhost:8080/library
    ,则必须再次将他重定向到
    userNotActive
    此处提供详细答案。仅仅放一个链接是不够的。@mentalurg好的,添加了答案细节,只是不想不必要地重复。
    public function __construct(Auth $auth)
        {
            $this->auth = $auth;
        }