以下は、Laravel チュートリアル コラムからの Laravel Auth の原則の簡単な分析です。困っている友人の役に立てば幸いです。
同社は最近 Laravel-admin をバックエンドとして使用し、Laravel フレームワークにさらされているため、Laravel コミュニティのパワーとエコロジーは素晴らしいと言わざるを得ません。確かに非常に強力です。
ただし、社内業務はすべて Java 側にあり、バックエンドは JavaApi の調整だけなので、Laravel の機能を大幅に削減する必要があります。ここでビジネスを分離し、保存するだけです テーブルは 3 つあり、Laravel-admin に付属しているテーブルです。
Laravel-admin には 9 つのテーブルが付属していますが、ユーザーのログイン業務はすべて API 側に格納されているため、組み込みのテーブル関数は諦めました。したがって、API ログイン ロジックを自分で実装する必要があり、Laravel Auth 認証を使用する必要があります。
Principle Interpretation
// 使用下面这个命令Laravel会自动为我们生成Auth路由和认证模块。跟着代码往下解读。 php artisan make:auth // Http/Controllers/Auth/LoginController 使用了 AuthenticatesUsers
このうち、次の 3 つのメソッドはすべてのログイン ロジックを説明します。
public function login(Request $request) { $this->validateLogin($request); if ($this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } // 这里尝试登录系统, if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } $this->incrementLoginAttempts($request); return $this->sendFailedLoginResponse($request); } protected function attemptLogin(Request $request) { return $this->guard()->attempt( $this->credentials($request), $request->has('remember') ); } protected function guard() { return Auth::guard(); }
コントローラーは Auth::guard() を探しますが、この Auth::guard() は何ですか?
まず第一に、Auth はシステムのシングルトンであり、プロトタイプは
Illuminate\Auth\AuthManager;
にあります。名前が示すように、認証ファクトリー モードのインターフェイス Guards() を実装する認証管理モジュールです。
public function __construct($app) { $this->app = $app; $this->userResolver = function ($guard = null) { return $this->guard($guard)->user(); }; } // Auth::guard();就是调用了这个方法。 public function guard($name = null) { // 首先查找$name, 没有就使用默认的驱动, $name = $name ?: $this->getDefaultDriver(); // 意思就是要实例化出这个驱动并且返回, return isset($this->guards[$name]) ? $this->guards[$name] : $this->guards[$name] = $this->resolve($name); } // 默认的驱动是从配置文件里面读取的,/config/auth.php default配置项 public function getDefaultDriver() { return $this->app['config']['auth.defaults.guard']; } // 这里是构造Auth-guard驱动 protected function resolve($name) { $config = $this->getConfig($name); if (is_null($config)) { throw new InvalidArgumentException("xxx"); } // 这里是如果你自己实现的驱动就返回 if (isset($this->customCreators[$config['driver']])) { return $this->callCustomCreator($name, $config); } // 这里是系统默认两个类分别是 // session 和 token 这里主要讲 sessionGuard . $driverMethod = 'create'.ucfirst($config['driver']).'Driver'; if (method_exists($this, $driverMethod)) { return $this->{$driverMethod}($name, $config); } throw new InvalidArgumentException("xxx"); }
次に、設定ファイル auth を見てみましょう。 php
// Auth::guard() ,不传参数,就调用默认的default.guard , 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], // 系统的guard .默认支持 "database", "eloquent",意思就是说你的provider必须是这两个实例中的一个, 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], // 这个就是上面的provider了,你使用哪一个provider作为你的Auth::guard()返回的 // 模型 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
つまり結局のところ、デフォルト設定では Auth::guard() が sessionGuard を返してくれるのです
主に以下の 4 つのメソッドを見てください
namespace Illuminate\Auth; class SessionGuard{ public function attempt(array $credentials = [], $remember = false) { // 这里触发 试图登录事件,此时还没有登录 $this->fireAttemptEvent($credentials, $remember); $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials); // 这里会调用hasValidCredentials,其实就是验证用户名和密码的一个过程 if ($this->hasValidCredentials($user, $credentials)) { // 如果验证通过了,就调用login方法 . $this->login($user, $remember); return true; } // 否则就触发登录失败事件,返回假 $this->fireFailedEvent($user, $credentials); return false; } // 这里是登录用户的操作,就是说调用这个方法已经是合法用户了,必须是一个 // AuthenticatableContract 的实例 . public function login(AuthenticatableContract $user, $remember = false) { // 直接更新session,这里就是把session存起来,session的键在该方法的 // getName() 里边, $this->updateSession($user->getAuthIdentifier()); if ($remember) { $this->ensureRememberTokenIsSet($user); $this->queueRecallerCookie($user); } // 触发登录事件,已经登录了这个时候, $this->fireLoginEvent($user, $remember); // 将user对象保存到sessionGuard , 后续的类访问Auth::user();直接拿到 $this->setUser($user); } // 这里就是经常使用到的 Auth::user()了,具体如何返回看AuthManager里面的 // __call public function user() { if ($this->loggedOut) { return; } if (! is_null($this->user)) { return $this->user; } // 这里读取session拿到user的id , $id = $this->session->get($this->getName()); $user = null; // 如果拿到了id ,查找到该user if (! is_null($id)) { if ($user = $this->provider->retrieveById($id)) { $this->fireAuthenticatedEvent($user); } } $recaller = $this->recaller(); if (is_null($user) && ! is_null($recaller)) { $user = $this->userFromRecaller($recaller); if ($user) { $this->updateSession($user->getAuthIdentifier()); $this->fireLoginEvent($user, true); } } return $this->user = $user; } // 这里就直接返回用户id了, public function id() { if ($this->loggedOut) { return; } return $this->user() ? $this->user()->getAuthIdentifier() : $this->session->get($this->getName()); } }
一般的に、ユーザーのログイン プロセスは完了です。簡単なプロセスは
//伪代码 $credentials = $request()->only(['username' ,'password']); if(Auth::guard("session")->attempt($credentials)){ // 登录成功 }else{ // 登录失败 }
ユーザーがログインした後にのみアクセスできるコントローラー/メソッドを実装する
Route::get("/home")->middleware("auth"); // auth Middleware 是在app/Http/Kernel中注册的, // 类名是 \Illuminate\Auth\Middleware\Authenticate::class // 解析过程实质上是这个方法: public function handle($request, Closure $next, ...$guards) { $this->authenticate($guards); return $next($request); } protected function authenticate(array $guards) { // 默认情况下会去 Auth中寻找authenticate这个方法 if (empty($guards)) { return $this->auth->authenticate(); } // 如果middleware中传了参数,会遍历一遍,不通过就抛出异常 foreach ($guards as $guard) { if ($this->auth->guard($guard)->check()) { return $this->auth->shouldUse($guard); } } throw new AuthenticationException('Unauthenticated.', $guards); } //sessionGuard 中的authenticate其实也就是调用了一遍user方法。 public function authenticate() { if (! is_null($user = $this->user())) { return $user; } throw new AuthenticationException; }
これは、初めて記事を書きますので間違い等ありましたらご指摘ください、よろしくお願いします!
以上がLaravel Auth の原則の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。