【问题标题】:Laravel authenticate users when their school is active当学校处于活动状态时,Laravel 对用户进行身份验证
【发布时间】:2020-01-25 09:10:25
【问题描述】:

我们正在为学校制作一个 laravel 项目。我们有一个学校数据库,里面有教师、员工等用户。我的问题是如何防止来自特定学校的特定用户登录他们的学校状态标记为 = 0 或在我们的数据库中为非活动状态?

学校表 +--------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(191) | NO | UNI | NULL | | | description | text | NO | | NULL | | | logo | varchar(191) | YES | | NULL | | | status | int(11) | NO | | 1 | | | updated_by | varchar(191) | YES | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +--------------+------------------+------+-----+---------+----------------+

用户表 +-------------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(191) | NO | | NULL | | | email | varchar(191) | NO | UNI | NULL | | | password | varchar(191) | NO | | NULL | | | role | int(11) | NO | | 0 | | | school_id | int(11) | NO | | NULL | | | gender | int(11) | NO | | 1 | | | birthdate | date | YES | | NULL | | | address | varchar(191) | NO | | | | | phone | varchar(191) | YES | | NULL | | | remember_token | varchar(100) | YES | | NULL | | +-------------------+------------------+------+-----+---------+----------------+

登录控制器.php

class LoginController extends Controller
{

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    // protected $redirectTo = '/admin';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        // $this->middleware('guest')->except('logout');
    }



}```

用户模型

  public function schools()
    {
        return $this->belongsTo('App\School', 'school_id');
    }

学校模型

 public function users(){
        return $this->hasMany(User::class);
    }

我的 LoginController 只使用 AuthenticateUsers 函数,我不知道如何覆盖它或为我创建一个新函数。提前致谢。

【问题讨论】:

    标签: php mysql laravel authentication


    【解决方案1】:

    我建议为登录路由创建一个中间件,该中间件将处理用户所在学校的状态值。如果它无效,您应该处理它,例如,您向用户抛出异常,学校处于非活动状态。

    更多信息在这里:https://laravel.com/docs/master/middleware


    更新:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Contracts\Auth\Guard;
    
    class Authenticate
    {
        /**
         * The Guard implementation.
         *
         * @var Guard
         */
        protected $auth;
    
        /**
         * Create a new filter instance.
         *
         * @param \Illuminate\Contracts\Auth\Guard $auth
         */
        public function __construct(Guard $auth)
        {
            $this->auth = $auth;
        }
    
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request $request
         * @param  \Closure                 $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            if ($this->auth->schools()->status == 0) {
                return response('School is inactive!', 401);
            }
    
            return $next($request);
        }
    }
    

    并将新创建的中间件添加到 App\Http Kernel.php 类中。

    将以下行添加到变量$routeMiddleWare:

    'auth'                => \TIM\Http\Middleware\Authenticate::class,
    

    现在要做的最后一件事是将 'auth' 键添加到 Route group。

    Route::group([
        'middleware' => ['auth'],
    ], function () {
    // your routes
    }
    

    【讨论】:

    • 先生,我该怎么做。我对中间件以及如何实现它们并不是很熟悉。我应该在那里写一个查询吗?
    • 你好@Vince。查看更新的答案,我将指导您如何归档它。
    【解决方案2】:

    在LoginController 中,您可以覆盖authenticated 方法,当用户成功登录时会触发此函数。

    public function authenticated(Request $request, $user)
    {
        if ($user->schools()->status === 0) {
            Auth::logout($user);
    
            abort(403, 'Your school is not active.');
        }
    }
    
    1. 我在这里假设您已经设置了关系,如果没有,那么只需选择用户注册的学校并从中进行检查。
    2. 我建议重写authenticated 方法而不是其他方法的原因是,此时您知道用户已正确登录,因此与attemptLogin 相比,它是处理它的正确位置。

    【讨论】:

    • 我已经在模型中设置了关系先生。让我试试这个。
    • 我应该在哪里插入此代码先生?我得到一个错误:Type error: Argument 1 passed to App\Http\Controllers\Auth\LoginController::authenticated() must be an instance of App\Http\Controllers\Auth\Request, instance of Illuminate\Http\Request given, called in C:\Users\bustillo-ronald\Desktop\safe-web\vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php on line 104
    • 我已经放了我的模型先生,因为我收到了Call to undefined method Illuminate\Database\Query\Builder::school() 的新错误,其中一些答案是关于我的模型的。 @Script47
    【解决方案3】:

    使用连接查询。只需在 users 表中添加 school_id 。例如

    self::where('users.school_id', $id)->where('schools.status',0)
    

    【讨论】:

    • 我应该在哪里插入这个查询先生?
    • 在我的用户迁移中先生?接下来我该怎么做?我必须在登录控制器中编写一个函数吗?
    • 所有查询都应该在模型中而不是在控制器中。首先只需添加迁移文件,然后在 users 表中添加 school_id
    • 然后创建一个查询
    • 先生,我应该把我的查询放在哪里? self::where('users.school_id', $id)-&gt;where('schools.status',0)
    【解决方案4】:

    您可以覆盖attemptLogin 函数来检查该字段。

    protected function attemptLogin(Request $request)
    {
        //
        // Query the school status here and return false if status === 0.
        //
    
        return $this->guard()->attempt(
            $this->credentials($request), $request->filled('remember')
        );
    }
    

    【讨论】:

    • 我可以在这里使用原始 sql 查询吗?
    • 是的,你可以。但是,您必须查询用户的电子邮件地址,因为您还没有用户的 ID。
    • select users.email, users.password from users join schools on users.school_id = schools.id where schools.status = 0; 先生,这是正确的查询吗?
    猜你喜欢
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2015-09-10
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多