前期准備
Laravel的權限配置文件位於 config/auth.php,Laravel的認證組件由“guards”和“providers”組成,
Guard 通過 session 來維護用戶登錄的狀態。Provider 是登錄以及訪問頁面的時候獲取用戶的信息。本篇主要講的是如何自定義Provider ,獲取用戶信息。
config/auth.php文件
Laravel提供了兩種guard,web以及api,采取默認的web認證。在guards的web中,用了users提供者。接下來就需要注意了,我們自定義了服務提供者,就需要換到新的providers。首先,定義一個使用新驅動的provider:
'providers' => [
'users' => [
'driver' => 'Focus', //名稱自定義,這里為Focus
'model' => App\Models\User::class, //Model放在Models文件夾下
],
],
Notes: 默認提供了兩種驅動database和eloquent,而這兩種的提供者分別是DatabaseUserProvider和EloquentUserProvider,都處於laravel\framework\src\Illuminate\Auth文件夾下,實現了UserProvider,我們自定義的 Focus provider 也將實現UserProvider。
生成路由和視圖
php artisan make:auth //命令可快速生成認證所需要的路由和視圖
Http/Controllers 和 resources/views下會相應生成控制器和視圖
默認用的Email,我們用username
LoginController:
//添加此方法,返回username
public function username(){
return 'username';
}
login.blade.php:
將郵箱改為域賬號,email 改為username
數據庫
修改.env配置中的數據庫信息。
php artisan make:model Models/User // 使用命令創建User模型
默認User是繼承Model的,需要修改。
use Illuminate\Foundation\Auth\User as Authenticatable; //引入Authenticatable
class User extends Authenticatable
{
protected $table = 'employee';
protected $primaryKey = 'employee_id';
//can set all fields to user model
protected $guarded = [];
}
為什么要引入Authenticatable呢,是因為Authenticatable實現了Illuminate\Contracts\Auth\Authenticatable接口,而FocusUserProvider 需要用到接口的實現。
創建擴展
在app下新建 Extensions/FocusUserProvider 文件,參考DatabaseUserProvider和EloquentUserProvider,實現UserProvider:
namespace App\Extensions;
use App\Services\LdapValidator;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\UserProvider;
use \Illuminate\Contracts\Auth\Authenticatable;
class LaravelUserProvider implements UserProvider {
protected $model;
public function __construct($model)
{
$this->model = $model;
}
//登錄成功后,通過此方法獲取用戶信息,返回匹配該ID的 Authenticatable 實現
public function retrieveById($identifier) {
//此處可以將信息放入緩存,緩解數據庫壓力。
$model = $this->createModel();
return $model->newQuery()
->where($model->getAuthIdentifierName(), $identifier)
->first();
}
public function retrieveByToken($identifier, $token) {
}
public function updateRememberToken(Authenticatable $user, $token) {
}
//該方法可以根據賬號名去查詢數據庫是否存在匹配的賬號
public function retrieveByCredentials(array $credentials) {
if (empty($credentials)) {
return;
}
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value) {
if (! Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
return $query->first();
}
//該方法可以驗證密碼是否正確,因為我們是ldap登錄,可以在此驗證域賬號
public function validateCredentials(Authenticatable $user, array $credentials) {
//LdapValidator類是為了驗證域密碼的,放在了app/Services,在上面已經引入
$Ldap = new LdapValidator($user->username, $credentials['password']);
return $Ldap->validatePassword();
}
/**
* Create a new instance of the model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function createModel()
{
$class = '\\'.ltrim($this->model, '\\');
return new $class;
}
}
注冊提供者
Laravel 提供了AuthServiceProvider, 我們可以在這里注冊。
public function boot()
{
$this->registerPolicies();
//Focus為auth.php里面定義的驅動
Auth::provider('Focus', function($app, array $config){
return new FocusUserProvider ($config['model']);
});
}
下面就可以訪問http://你的域名/login 登錄系統