国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

用戶認證

用戶認證


用戶認證

引言

{tip} 想要快速開始嗎? 只要在一個新的 Laravel 應用程序中運行 php artisan make:authphp artisan migrate 就可以了。 然后,把你的瀏覽器導航到 http://your-app.test/register 或者其他任意一個分配給你的程序的 URL。這兩個命令將負責構建整個認證系統(tǒng)!

Laravel 使得實現身份驗證非常簡單。 事實上,幾乎所有的配置都是現成的。 身份驗證配置文件位于 config/auth.php, 其中包含幾個有良好文檔記錄的選項,用于調整身份驗證服務的行為。

在其核心,Laravel 的認證設施由 “警衛(wèi)” 和 “提供者” 組成。守衛(wèi)決定如何對每個請求的用戶進行身份驗證。比如,Laravel 帶有一個 session 保護,它使用會話存儲和 Cookies 來維護狀態(tài)。

提供者決定如何從持久儲存中檢索用戶。 Laravel 支持使用 Eloquent 和數據庫查詢生成器檢索用戶。但是,你可以根據應用程序的需要來自由定義其他提供者。

如果這些聽起來讓你很困惑,別擔心!許多應用程序永遠不需要修改默認的身份驗證配置。

數據庫注意事項

默認情況下, Laravel 包含一個 App\User Eloquent model 在你的 app 目錄下。 這個模型可與默認的 Eloquent 身份驗證驅動程序一起使用。如果你的應用程序沒有使用 Eloquent,你可以用 database 身份驗證驅動程序,它用的是 Laravel 查詢生成器。

當為 App\User 模型生成數據庫架構時,確保密碼的長度至少為 60 個字符。保持默認的字符串長度為 255 個字符是一個不錯的選擇。

另外,你應該驗證 “users”(或等效)表是否包含一個可空的,含有 100 個字符的 remember_token 字符串。此列將用于存儲用戶登錄應用程序時選擇 “記住我” 選項的令牌。

用戶認證快速指南

Laravel 附帶了幾個預構建的身份驗證控制器,它們位于 App\Http\Controllers\Auth 命名空間中。RegisterController 處理新的用戶注冊,LoginController 處理身份驗證,ForgotPasswordController 處理用于重置密碼的電子郵件鏈接,ResetPasswordController 包含重置密碼的邏輯。這些控制器中的每一個都使用一個特性來包含它們的必要方法。對于許多應用程序,您根本不需要修改這些控制器。

路由

Laravel 提供了一種快速的方法,可以使用一個簡單的命令來搭建認證所需的所有路由和視圖:

php artisan make:auth

此命令應該用于新應用程序,并將安裝布局視圖、注冊和登錄視圖以及所有身份驗證端點的路由。還將生成一個 HomeController 來處理應用程序儀表板的登錄后請求。

{tip} 如果應用程序不需要注冊,可以通過刪除新創(chuàng)建的 RegisterController 并修改路由聲明來禁用它: Auth::routes(['register' => false]);

視圖

如前一節(jié)所述, php artisan make:auth 命令將創(chuàng)建認證所需的所有視圖,并將它們放在 resources/views/auth 目錄中。

make:auth 命令還將創(chuàng)建一個包含應用程序基本布局的 resources/views/layouts 目錄。所有這些視圖都使用了 Bootstrap CSS 框架,但是你可以自由地定制它們。

認證

現在已經給認證的控制器設置好了路由和視圖,你可以在應用中注冊和認證新用戶了!因為控制器已經默認包含了驗證用戶是否存在和保存用戶到數據庫中的認證邏輯(通過 traits 實現的),現在你已經可以在瀏覽器中訪問應用了。

自定義路徑

當用戶認證成功,他們會被重定向到 /home 這個 URI 下。你可以在 LoginController,RegisterController, ResetPasswordController,還有 VerificationController 控制器中定義 redirectTo 屬性來自定義驗證后的重定向位置:

protected $redirectTo = '/';

接下,你應該修改 RedirectIfAuthenticated 中間件中的 handle 方法,以便在重定向用戶時重定向到新的 URI。

如果重定向路徑需要自定義生成邏輯,你可以定義 redirectTo 方法替代 redirectTo 屬性:

protected function redirectTo(){ 
   return '/path';
 }

{提示}  redirectTo 方法優(yōu)先于 redirectTo 屬性。

自定義用戶名

Laravel 默認使用 email 字段來認證。如果你想使用其他的字段,可以在 LoginController 控制器里面定義一個 username 方法:

public function username(){  
  return 'username';
 }

自定義看守器

你還可以自定義用戶認證和注冊的 「看守器」。要實現這一功能,需要在 LoginController,RegisterControllerResetPasswordController 中定義 guard 方法。該方法會返回一個看守器實例:

use Illuminate\Support\Facades\Auth;protected function guard(){ 
   return Auth::guard('guard-name');
 }

自定義驗證 / 存儲

為了修改新用戶在注冊時所需要填寫的表單字段,或者自定義如何將新用戶存儲到數據庫中,你可以修改  RegisterController 類。該類負責驗證和創(chuàng)建新用戶。

RegisterController 類的 validator 方法包含了驗證新用戶的規(guī)則,你可以隨心所欲地自定義該方法。

RegisterControllercreate 方法負責使用  Eloquent ORM 在數據庫中創(chuàng)建新的 App\User 記錄。你可以根據數據庫的需要自定義該方法。

檢索認證用戶

你可以通過 Auth facade 來訪問已認證的用戶:

use Illuminate\Support\Facades\Auth;
// 獲取當前通過認證的用戶...
$user = Auth::user();
// 獲取當前通過認證的用戶 ID...
$id = Auth::id();

或者,你可以通過 Illuminate\Http\Request 實例來訪問已認證的用戶。別忘了,類型提示的類會被自動注入到你的控制器方法中:

<?php
   namespace App\Http\Controllers;
   use Illuminate\Http\Request;
   class ProfileController extends Controller{ 
    /**
     * 更新用戶資料。
     *
     * @param  Request  $request
     * @return Response
     */  
   public function update(Request $request)  
     {       
      // $request->user() 返回一個認證用戶實例...   
      }
  }

確定當前用戶是否已經認證

你可以使用 Auth facade 的 check 方法來檢查用戶是否已認證。如果已認證,將會返回 true

use Illuminate\Support\Facades\Auth;
if (Auth::check()) {   
 // 用戶已經登錄了...
}

{提示} 雖然可以使用 check 方法確認用戶是否被認證,但是在允許用戶訪問的某些路由 / 控制器之前,通常還是會使用中間件來驗證用戶是否進行過身份驗證。想要了解更多信息,請查看有關 保護路由 的文檔。

保護路由

路由中間件 可以用于只允許通過認證的用戶訪問給定的路由。Laravel 自帶了一個 auth 中間件,它定義在 Illuminate\Auth\Middleware\Authenticate 中。由于這個中間件已經在 HTTP 內核中注冊,你只需把這個中間件附加到路由定義中:

Route::get('profile', function () {  
  // 只有認證過的用戶可以進入...
 })->middleware('auth');

當然,如果你使用 控制器,你可以在控制器的構造函數中調用  middleware 方法來直接將其附加到路由定義中:

public function __construct(){  
  $this->middleware('auth');
}

重定向未認證的用戶

auth 中間件檢測到一個未認證用戶時,它會把用戶重定向到名為 login 的 命名路由上。
您可以通過修改 app/Http/Middleware/Authenticate.php 文件中的 redirectTo 函數來修改此行為:

/**
 * Get the path the user should be redirected to.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return string
 */
 protected function redirectTo($request){ 
    return route('login');
 }

指定看守器

當你把 auth 中間件添加到路由中時,同時也能指定使用哪個看守器進行用戶認證。指定的看守器應該對應 auth.php 配置文件中 guards 數組中的的一個鍵:

public function __construct(){ 
   $this->middleware('auth:api');
}

登錄限流

如果你使用 Laravel 內置的 LoginController 類,Illuminate\Foundation\Auth\ThrottlesLogins trait 已經包含在該控制器中了。默認情況下,如果用戶多次嘗試卻無法提供正確的登錄憑據,那么該用戶在一分鐘內將不能再次嘗試登錄。這種限流策略基于用戶的用戶名 / 郵箱地址及其 IP 地址的唯一性。

手動驗證用戶

不一定非要在 Lavarel 中使用驗證控制器。如果選擇刪除這些控制器,就需要直接使用 Lavarel 驗證類。別擔心,很容易!

可以借助 Auth facade 訪問 Laravel 服務,因此需要在類的開頭導入  Auth 。下面來看看 attempt 方法:

<?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    class LoginController extends Controller{  
     /**
     * 處理身份驗證嘗試。
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return Response
     */   
    public function authenticate(Request $request)   
     {       
        $credentials = $request->only('email', 'password');      
        if (Auth::attempt($credentials)) {        
            // 身份驗證通過...           
           return redirect()->intended('dashboard');    
             }   
           }
        }

attempt 方法的每個參數是一個關聯數組。數組值用于在數據庫中查找用戶。在上面的例子中,將通過 email 列的值查找用戶。如果找到該用戶,將用存儲在數據庫中的哈希密碼與數組中的 password 值做比較。不需要對 password 做哈希運算,框架在與數據庫中的哈希密碼做比較前自動對此值做哈希運算。如果兩個哈希值匹配,將為該用戶建立驗證通過的 session。

如果驗證成功, attempt 方法返回  true ,否則返回 false 。

重定向中的 intended 方法將經由身份驗證中間件將用戶重定向到身份驗證前截獲的 URL 。如果預期目標不存在,可以為此方法指定一個回退 URI 。

指定額外條件

除了用戶的電子郵件和密碼之外,還可以向身份驗證查詢添加其他條件。例如, 我們可以驗證用戶是不是已經被標記為 「激活」:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {  
  // 用戶存在,已激活且未被禁用。
 }

{note} 在這些例子中, email 不是必須的選項,它只用來做示范。你應該使用與你的數據庫中 「用戶名」 對應的列名。

訪問指定的看守器實例

可以使用 Auth facade 的 guard 方法指定想要使用的看守器實例。這允許你使用完全獨立的可驗證模型或用戶表來管理應用程序各個部分的驗證。

傳遞給 guard 方法的看守器名稱需要與 auth.php 配置中的配置項之一相匹配:

if (Auth::guard('admin')->attempt($credentials)) { 
   //
 }

登出

用戶登出需要使用 Auth facade 的 logout 方法。它會清除用戶會話(session)中的用戶驗證信息:

Auth::logout();

記住用戶

如果想在應用中提供 「記住我」功能,可以給 attempt 方法傳遞一個布爾值作為其第二個參數,這會無限期保持用戶身份驗證,直到用戶手動登出。用戶表需要包含字符串類型的 remember_token 列用于存儲令牌。

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) { 
   // 用戶被記住...
}

{tip} 如果使用了 Laravel 內置的 LoginController,「記住」用戶的正確邏輯已經由控制器所用的 traits 實現。

如果啟用了「記住用戶」,可以使用 viaRemember 方法判斷是否使用了「記住我」cookie 對用戶做身份驗證:

if (Auth::viaRemember()) { 
   //
}

其它身份驗證方法

驗證用戶實例

如果要將已經存在的用戶登入應用,可以調用 login 方法,并以用戶實例作為其參數 。該對象必須實現 Illuminate\Contracts\Auth\Authenticatable 契約 。Laravel 自帶的 App\User 模型已經實現了這個接口:

Auth::login($user);
// 登錄并「記住」給定的用戶...
Auth::login($user, true);

使用如下方式指定想要的看守器實例:

Auth::guard('admin')->login($user);

通過 ID 驗證用戶身份

可以使用 loginUsingId 方法通過 ID 將用戶登錄到應用。這個方法接受希望驗證身份用戶的主鍵:

Auth::loginUsingId(1);
// 登錄并「記住」給定用戶...
Auth::loginUsingId(1, true);

僅驗證一次用戶身份

可以使用 once 方法在單次請求中將用戶登錄到應用中。這樣做將不使用 session 或 cookies,這意味著此方法有助于構建一個無狀態(tài) API:

if (Auth::once($credentials)) {
    //
  }

HTTP 基礎認證

HTTP 基礎認證 提供了一種快速方法來驗證你應用程序中的用戶,而無需設置專用的「登錄」頁面。 開始之前, 先把 auth.basic 中間件 附加到你的路由中。auth.basic 中間件已包含在 Laravel 框架中,所以你不需要定義它:

Route::get('profile', function () { 
   // 只有認證過的用戶可以進入...
 })->middleware('auth.basic');

將中間件附加到路由后,在瀏覽器中訪問此路由時將自動提示您輸入憑據。默認的,auth.basic 中間件把用戶記錄上的 email 字段 作為「用戶名」。

FastCGI 的注意事項

如果你正使用 PHP FastCGI 模式,HTTP 基礎認證可能無法正常工作。需要把下面幾行添加到你的 .htaccess 文件中:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

無狀態(tài) HTTP 基礎認證

你也可以使用 HTTP 基礎身份驗證,而無需在會話中設置用戶標識符 cookie,這對 API 的身份驗證特別有用。為此 ,請定義一個中間件 它將調用 onceBasic 方法。如果 onceBasic 方法沒有返回任何響應,那么請求就可以進一步傳遞到應用程序中:

<?php
  namespace App\Http\Middleware;
  use Illuminate\Support\Facades\Auth;
  class AuthenticateOnceWithBasicAuth{   
       /**
     * 處理傳入的請求
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */  
  public function handle($request, $next)  
    {       
       return Auth::onceBasic() ?: $next($request);  
     }
   }

接著, 注冊路由中間件 并將它附加到路由:

Route::get('api/user', function () {  
  // 只有認證過的用戶可以進入...
})->middleware('auth.basic.once');

退出

要手動把用戶從應用中退出登錄,你可以使用 Auth facade 上的 logout 方法。這將清除用戶會話中的身份認證信息:

use Illuminate\Support\Facades\Auth;Auth::logout();

讓其它設備上的 Session 失效

Laravel 還提供了一種機制,用于將其它設備上的用戶 Session 失效和「注銷」,而不會使其當前設備上的 Session 失效。首先,你需要保證 Illuminate\Session\Middleware\AuthenticateSession 中間件在你的 app/Http/Kernel.php 類中的 web 中間件組中,并且沒有被注釋掉:

'web' => [   
    // ...
    \Illuminate\Session\Middleware\AuthenticateSession::class,  
    // ...
  ],

然后, 你就可以使用 Auth facade 上的 logoutOtherDevices 方法。此方法要求用戶提供其當前密碼,你的應用程序應通過輸入表單接受該密碼:

use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($password);

{note} 當調用 logoutOtherDevices 方法后,用戶的其它 Session 將完全失效,這意味著他們將「退出」他們之前通過身份認證的所有看守器。

添加自定義的看守器

你可以使用 Auth facade 的 extend 方法來定義自己的身份驗證看守器。你應該在 服務提供器 中調用  extend 方法。由于 Laravel 已經附帶了 AuthServiceProvider,我們可以將代碼放在該提供器中:

<?php
  namespace App\Providers;
  use App\Services\Auth\JwtGuard;
  use Illuminate\Support\Facades\Auth;
  use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
  class AuthServiceProvider extends ServiceProvider{   
      /**
     * 注冊任意應用認證/授權服務。
     *
     * @return void
     */   
  public function boot()  
   {      
     $this->registerPolicies();        
     Auth::extend('jwt', function ($app, $name, array $config) {         
       // 返回一個 Illuminate\Contracts\Auth\Guard 實例...           
        return new JwtGuard(Auth::createUserProvider($config['provider']));     
         });   
    }}

正如你在上面的示例中所看到的,傳遞給 extend 方法的回調應該返回一個實現 Illuminate\Contracts\Auth\Guard 接口的實例。這個接口包含了一些你需要在自定義的看守器中實現的方法。當你的自定義看守器定義完成之后,你可以在 auth.php 配置文件的 guards 配置中使用這個看守器:

'guards' => [  
  'api' => [     
     'driver' => 'jwt',        
     'provider' => 'users',    
     ],
  ],

請求閉包看守器

實現基于 HTTP 請求的自定義身份驗證系統(tǒng)的最簡單方法,是使用 Auth::viaRequest 方法。此方法允許您使用單個閉包來快速定義身份驗證過程。

首先,在 AuthServiceProviderboot 方法中調用 Auth::viaRequest 方法。viaRequest 方法接受一個看守器名稱作為其第一個參數。此名稱可以是描述你自定義看守器的任何字符串。傳遞給該方法的第二個參數應該是一個閉包函數,它接收傳入的 HTTP 請求并返回一個用戶實例,或者,如果驗證失敗,則為 null

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
  /**
 * 注冊任意應用認證/授權服務。
 *
 * @return void
 */
 public function boot(){  
   $this->registerPolicies();  
    Auth::viaRequest('custom-token', function ($request) {     
       return User::where('token', $request->token)->first();  
       });
     }

當你完成了自定義看守器后,就可以在 auth.php 配置文件的 guards 配置中使用這個看守器:

'guards' => [   
 'api' => [      
   'driver' => 'custom-token',  
   ],
 ],

添加自定義用戶提供器

如果不使用傳統(tǒng)的關系數據庫存儲用戶,就需要使用自己的身份驗證用戶提供器擴展 Lavarel??梢允褂?Auth facade 的 provider 方法自定義用戶提供器:

<?php
    namespace App\Providers;
    use Illuminate\Support\Facades\Auth;
    use App\Extensions\RiakUserProvider;
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
    class AuthServiceProvider extends ServiceProvider{   
        /**
     * 注冊任意應用身份驗證 / 授權服務Register any application authentication / authorization services.
     *
     * @return void
     */   
      public function boot()   
       {      
         $this->registerPolicies();       
         Auth::provider('riak', function ($app, array $config) {         
            // 返回 Illuminate\Contracts\Auth\UserProvider 實例...            
            return new RiakUserProvider($app->make('riak.connection'));       
           });   
        }}

一旦使用 provider 方法注冊完畢,就可以在 auth.php 配置文件中切換到新的用戶提供器。先定義一個使用新驅動的 provider

'providers' => [  
  'users' => [      
    'driver' => 'riak',  
      ],
  ],

隨后就可以在 guards 配置中使用這個提供器:

'guards' => [   
    'web' => [     
       'driver' => 'session',        
       'provider' => 'users',    
     ],
  ],

用戶提供器契約

Illuminate\Contracts\Auth\UserProvider 實現僅負責從 MySQL、Riak 等持久化存儲系統(tǒng)中提取 Illuminate\Contracts\Auth\Authenticatable 實現。無論用戶如何存儲及用于表示它的類是什么類型,這兩個接口都允許 Laravel 身份驗證機制繼續(xù)運行:

我們來看看 Illuminate\Contracts\Auth\UserProvider 契約:

<?php
    namespace Illuminate\Contracts\Auth;
    interface UserProvider {  
      public function retrieveById($identifier);    
      public function retrieveByToken($identifier, $token);    
      public function updateRememberToken(Authenticatable $user, $token);    
      public function retrieveByCredentials(array $credentials);    
      public function validateCredentials(Authenticatable $user, array $credentials);
     }

retrieveById 函數通常接受用于表示類的 key(如 MySQL 數據庫中自動遞增的 ID)作為參數,并獲取和返回與這個 ID 匹配的 Authenticatable 實現。

retrieveByToken 函數通過用戶的唯一 $identifier 和存儲在 remember_token 列的 「記住我」 令牌獲取用戶。與前一方法相同,它返回 Authenticatable 實現。

updateRememberToken 方法用新  $token 更新  $userremember_token 列。在「記住我」登錄校驗成功或者用戶登出時分配「刷新令牌」。

在嘗試登錄到應用時,retrieveByCredentials 方法接受憑證數組傳遞給 Auth::attempt 方法。此方法在底層持久化存儲中「查詢」與這些憑證匹配的用戶。通常,此方法運行一個基于 $credentials['username'] 的 「where」 條件,它應該返回一個 Authenticatable 實現。此方法不就嘗試進行任何密碼校驗或身份驗證。

validateCredentials 方法應該比較給定的 $user$credentials 來驗證用戶身份。例如,此方法或許應該使用 Hash::check 來比較 $user->getAuthPassword() 的值與 $credentials['password'] 的值。它應該返回 truefalse ,以表明用戶密碼是否有效。

身份驗證契約

我們已經剖析了 UserProvider 的每個方法。下面再來看看 Authenticatable 契約。切記,用戶提供器的 retrieveById、 retrieveByTokenretrieveByCredentials 方法將返回此接口的實例:

<?php
   namespace Illuminate\Contracts\Auth;
   interface Authenticatable {   
      public function getAuthIdentifierName();    
      public function getAuthIdentifier();    
      public function getAuthPassword();    
      public function getRememberToken();    
      public function setRememberToken($value);    
      public function getRememberTokenName();
     }

這個接口很簡單。 getAuthIdentifierName 方法應該返回用戶 「主鍵」 列的名字, getAuthIdentifier 方法則返回用戶 「主鍵」。在 MySQL 后臺,它會是自增主鍵。 getAuthPassword 方法應該返回用戶的哈希密碼。此接口允許身份驗證系統(tǒng)與任一 User 類一直工作,不管使用的是哪種 ORM 或抽象存儲層。默認情況下,Laravel 的 app 目錄會包含一個實現了此接口的 User 類,你可以以這個實現示例作為參考。

事件

在身份驗證處理過程中 Laravel 引發(fā)了多種 事件 。 可以在  EventServiceProvider 中附著這些事件的監(jiān)聽器:

/**
 * 應用的事件監(jiān)聽器映射。
 *
 * @var array
 */
 protected $listen = [   
    'Illuminate\Auth\Events\Registered' => [     
       'App\Listeners\LogRegisteredUser',  
       ],  
     'Illuminate\Auth\Events\Attempting' => [     
        'App\Listeners\LogAuthenticationAttempt', 
         ],  
      'Illuminate\Auth\Events\Authenticated' => [    
         'App\Listeners\LogAuthenticated',   
        ],  
      'Illuminate\Auth\Events\Login' => [     
         'App\Listeners\LogSuccessfulLogin',   
        ],  
      'Illuminate\Auth\Events\Failed' => [     
         'App\Listeners\LogFailedLogin',   
        ], 
      'Illuminate\Auth\Events\Logout' => [      
           'App\Listeners\LogSuccessfulLogout',  
           ],   
       'Illuminate\Auth\Events\Lockout' => [     
         'App\Listeners\LogLockout',   
         ],  
       'Illuminate\Auth\Events\PasswordReset' => [     
         'App\Listeners\LogPasswordReset',   
         ],
      ];
本文章首發(fā)在 LearnKu.com 網站上。