認(rèn)證

2018-12-17 10:48 更新

介紹

Laravel 讓實(shí)現(xiàn)認(rèn)證機(jī)制變得非常簡單。事實(shí)上,幾乎所有的設(shè)置默認(rèn)就已經(jīng)完成了。有關(guān)認(rèn)證的配置文件都放在 config/auth.php 里,而在這些文件里也都包含了良好的注釋描述每一個(gè)選項(xiàng)的所對應(yīng)的認(rèn)證服務(wù)。

Laravel 默認(rèn)在 app 文件夾內(nèi)就包含了一個(gè)使用默認(rèn) Eloquent 認(rèn)證驅(qū)動(dòng)的 App\User模型。

注意:當(dāng)為這個(gè)認(rèn)證模型設(shè)計(jì)數(shù)據(jù)庫結(jié)構(gòu)時(shí),密碼字段至少有60個(gè)字符寬度。同樣,在開始之前,請先確認(rèn)您的 users (或其他同義) 數(shù)據(jù)庫表包含一個(gè)名為 remember_token 長度為 100 的string類型、可接受 null 的字段。這個(gè)字段將會被用來儲存「記住我」的 session token。也可以通過在遷移文件中使用 $table->rememberToken();                方法。 當(dāng)然, Laravel 5 自帶的 migrations 里已經(jīng)設(shè)定了這些字段。

假如您的應(yīng)用程序并不是使用 Eloquent ,您也可以使用 Laravel 的查詢構(gòu)造器做 database 認(rèn)證驅(qū)動(dòng)。

           

用戶認(rèn)證

Laravel 已經(jīng)預(yù)設(shè)了兩個(gè)認(rèn)證相關(guān)的控制器。 AuthController 處理新的用戶注冊和「登陸」,而 PasswordController 可以幫助已經(jīng)注冊的用戶重置密碼。

每個(gè)控制器使用 trait 引入需要的方法。在大多數(shù)應(yīng)用上,你不需要修改這些控制器。這些控制器用到的視圖放在 resources/views/auth 目錄下。你可以依照需求修改這些視圖。

用戶注冊

要修改應(yīng)用注冊新用戶時(shí)所用到的表單字段,可以修改 App\Services\Registrar 類。這個(gè)類負(fù)責(zé)驗(yàn)證和建立應(yīng)用的新用戶。

Registrarvalidator 方法包含新用戶時(shí)的驗(yàn)證規(guī)則,而 Registrarcreate 方法負(fù)責(zé)在數(shù)據(jù)庫中建立一條新的 User 記錄。你可以自由的修改這些方法。Registrar 方法是通過AuthenticatesAndRegistersUsers trait 的中的                AuthController 調(diào)用的。

手動(dòng)認(rèn)證

如果你不想使用預(yù)設(shè)的 AuthController,你需要直接使用 Laravel 的身份驗(yàn)證類來管理用戶認(rèn)證。別擔(dān)心,這也很簡單的!首先,讓我們看看 attempt 方法:

<?php namespace App\Http\Controllers;use Auth;use Illuminate\Routing\Controller;class AuthController extends Controller {

    /**
     * Handle an authentication attempt.
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password]))
        {
            return redirect()->intended('dashboard');
        }
    }}

           

attempt 方法可以接受由鍵值對組成的數(shù)組作為第一個(gè)參數(shù)。password 的值會先進(jìn)行 哈希。數(shù)組中的其他 值會被用來查詢數(shù)據(jù)表里的用戶。所以,在上面的示例中,會根據(jù) email 列的值找出用戶。如果找到該用戶,會比對數(shù)據(jù)庫中存儲的哈希過的密碼以及數(shù)組中的哈希過后的 password值。假設(shè)兩個(gè)哈希后的密碼相同,會重新為用戶啟動(dòng)認(rèn)證通過的                session。

如果認(rèn)證成功, attempt 將會返回 true。否則則返回 false。

**注意:**在上面的示例中,并不一定要使用 email 字段,這只是作為示例。你應(yīng)該使用對應(yīng)到數(shù)據(jù)表中的「username」的任何鍵值。

intended 方法會重定向到用戶嘗試要訪問的 URL , 其值會在進(jìn)行認(rèn)證過濾前被存起來。也可以給這個(gè)方法傳入一個(gè)預(yù)設(shè)的 URI,防止重定向的網(wǎng)址無法使用。

以特定條件驗(yàn)證用戶

在認(rèn)證過程中,你可能會想要加入額外的認(rèn)證條件:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])){
    // The user is active, not suspended, and exists.}

           

判斷用戶是否已驗(yàn)證

判斷一個(gè)用戶是否已經(jīng)登錄,你可以使用 check 方法:

if (Auth::check()){
    // The user is logged in...}

           

認(rèn)證用戶并且「記住」他

假如你想要在應(yīng)用中提供「記住我」的功能,你可以傳入布爾值作為 attempt 方法的第二個(gè)參數(shù),這樣就可以保留用戶的認(rèn)證身份(或直到他手動(dòng)登出為止)。當(dāng)然,你的 users 數(shù)據(jù)表必需包括一個(gè)字符串類型的 remember_token 列來儲存「記住我」的標(biāo)識。

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)){
    // The user is being remembered...}

           

假如有使用「記住我」功能,可以使用 viaRemember 方法判定用戶是否擁有「記住我」的 cookie 來判定用戶認(rèn)證:

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

           

以 ID 認(rèn)證用戶

要通過 ID 來認(rèn)證用戶,使用 loginUsingId 方法:

Auth::loginUsingId(1);

           

驗(yàn)證用戶信息而不登陸

validate 方法可以讓你驗(yàn)證用戶憑證信息而不用真的登陸應(yīng)用:

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

           

在單一請求內(nèi)登陸用戶

你也可以使用 once 方法來讓用戶在單一請求內(nèi)登陸。不會有任何 session 或 cookie 產(chǎn)生:

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

           

手動(dòng)登陸用戶

假如你需要將一個(gè)已經(jīng)存在的用戶實(shí)例登陸應(yīng)用,你可以調(diào)用 login 方法并且傳入用戶實(shí)例:

Auth::login($user);

           

這個(gè)方式和使用 attempt方法驗(yàn)證用戶憑證信息是一樣的。

用戶登出

Auth::logout();

           

當(dāng)然,假設(shè)你使用 Laravel 內(nèi)建的認(rèn)證控制器,預(yù)設(shè)提供了讓用戶登出的方法。

認(rèn)證事件

當(dāng) attempt 方法被調(diào)用時(shí),auth.attempt 事件 會被觸發(fā)。假設(shè)用戶嘗試認(rèn)證成功并且登陸了,auth.login 事件會被觸發(fā)。

           

取得經(jīng)過認(rèn)證的用戶

當(dāng)用戶通過認(rèn)證后,有幾種方式取得用戶實(shí)例。

首先, 你可以從 Auth facade 取得用戶:

<?php namespace App\Http\Controllers;use Auth;use Illuminate\Routing\Controller;class ProfileController extends Controller {

    /**
     * Update the user's profile.
     *
     * @return Response
     */
    public function updateProfile()
    {
        if (Auth::user())
        {
            // Auth::user() returns an instance of the authenticated user...        }
    }}

           

第二種,你可以使用 Illuminate\Http\Request 實(shí)例取得認(rèn)證過的用戶:

<?php namespace App\Http\Controllers;use Illuminate\Http\Request;use Illuminate\Routing\Controller;class ProfileController extends Controller {

    /**
     * Update the user's profile.
     *
     * @return Response
     */
    public function updateProfile(Request $request)
    {
        if ($request->user())
        {
            // $request->user() returns an instance of the authenticated user...        }
    }}

           

第三,你可以使用 Illuminate\Contracts\Auth\Authenticatable contract 類型提示。這個(gè)類型提示可以用在控制器的構(gòu)造方法,控制器的其他方法,或是其他可以通過服務(wù)容器 解析的類的構(gòu)造方法:

<?php namespace App\Http\Controllers;use Illuminate\Routing\Controller;use Illuminate\Contracts\Auth\Authenticatable;class ProfileController extends Controller {

    /**
     * Update the user's profile.
     *
     * @return Response
     */
    public function updateProfile(Authenticatable $user)
    {
        // $user is an instance of the authenticated user...    }}

           

           

保護(hù)路由

路由中間件 只允許通過認(rèn)證的用戶訪問指定的路由。Laravel 默認(rèn)提供了 auth 中間件,放在 app\Http\Middleware\Authenticate.php。 你需要做的只是將其加到一個(gè)路由定義中:

// With A Route Closure...Route::get('profile', ['middleware' => 'auth', function(){
    // Only authenticated users may enter...}]);// With A Controller...Route::get('profile', ['middleware' => 'auth', 'uses' => 'ProfileController@show']);

           

           

HTTP 基本認(rèn)證

HTTP 基本認(rèn)證提供了一個(gè)快速的方式來認(rèn)證用戶而不用特定設(shè)置一個(gè)「登入」頁。在您的路由內(nèi)設(shè)定 auth.basic 中間件則可啟動(dòng)這個(gè)功能:

用 HTTP 基本認(rèn)證保護(hù)路由

Route::get('profile', ['middleware' => 'auth.basic', function(){
    // Only authenticated users may enter...}]);

           

默認(rèn)情況下 basic 中間件會使用用戶的 email 列當(dāng)做「 username 」。

設(shè)定無狀態(tài)的 HTTP 基本過濾器

你可能想要使用 HTTP 基本認(rèn)證,但不會在 session 里設(shè)置用戶身份的 cookie,這在 API 認(rèn)證時(shí)特別有用。如果要這樣做,定義一個(gè)中間件并調(diào)用 onceBasic 方法:

public function handle($request, Closure $next){
    return Auth::onceBasic() ?: $next($request);}

           

如果你使用 PHP FastCGI,HTTP 基本認(rèn)證可能無法正常運(yùn)行。請?jiān)谀愕?.htaccess 文件內(nèi)新增以下代碼:

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

           

           

忘記密碼與重設(shè)

模型與數(shù)據(jù)表

大多數(shù)的 web 應(yīng)用程序都會提供用戶忘記密碼的功能。為了不讓開發(fā)者重復(fù)實(shí)現(xiàn)這個(gè)功能,Laravel 提供了方便的方法來發(fā)送忘記密碼通知及密碼重設(shè)的功能。

在開始之前,請先確認(rèn)您的 User 模型實(shí)現(xiàn)了 Illuminate\Contracts\Auth\CanResetPassword接口。當(dāng)然,默認(rèn) Laravel 的 User 模型本身就已實(shí)現(xiàn),并且引入Illuminate\Auth\Passwords\CanResetPassword來包括所有需要實(shí)現(xiàn)的接口方法。

生成 Reminder 數(shù)據(jù)表遷移

接下來,我們需要生成一個(gè)數(shù)據(jù)庫表來儲存重設(shè)密碼標(biāo)志。Laravel 默認(rèn)已經(jīng)包含了這個(gè)遷移表,放在 database/migrations 的目錄下。你所需要作的只有執(zhí)行遷移:

php artisan migrate

           

密碼重設(shè)控制器

Laravel 還包含了 Auth\PasswordController 其中包含重設(shè)用戶密碼的功能。甚至一些視圖,可以讓你直接開始使用!視圖放在 resources/views/auth 目錄下。你可以按照你的應(yīng)用程序設(shè)計(jì),自由的修改這些視圖。

你的使用者會收到一封 e-mail,內(nèi)含連接指向 PasswordController 中的 getReset 方法。這個(gè)方法會顯示密碼重設(shè)表單,允許用戶重新設(shè)定密碼。在密碼重新設(shè)定完之后,用戶將會自動(dòng)登錄到應(yīng)用中,然后被重定向到 /home。你可以通過 PasswordController 中的 redirectTo 來定義重設(shè)密碼后要重定向的位置:

protected $redirectTo = '/dashboard';

           

**注意:**默認(rèn)情況下,密碼重設(shè) tokens 會在一小時(shí)后過期。你可以修改 config/auth.php 文件中的 reminder.expire 更改 這個(gè)設(shè)定。

           

第三方登陸認(rèn)證

除了傳統(tǒng)的以表單進(jìn)行的認(rèn)證,Laravel 還提供了簡單、易用的方式,使用 Laravel Socialite 進(jìn)行 OAuth 認(rèn)證。Socialite 目前支持的認(rèn)證有 Facebook、 Twitter、Google、以及GitHub 和 Bitbucket 。            

如果要開始使用第三方認(rèn)證,請將下面的代碼加入到你的 composer.json 文件內(nèi):

"laravel/socialite": "~2.0"

           

接下來,在你的 config/app.php 配置文件中注冊 Laravel\Socialite\SocialiteServiceProvider。也可以注冊 facade

'Socialize' => 'Laravel\Socialite\Facades\Socialite',

           

你需要在應(yīng)用程序中加入 OAuth 服務(wù)所需的憑證。這些憑證都放在 config/services.php 配置文件里,并根據(jù)應(yīng)用的需求使用 facebook、twittergooglegithub 作為對應(yīng)的鍵值。例如:

'github' => [
    'client_id' => 'your-github-app-id',
    'client_secret' => 'your-github-app-secret',
    'redirect' => 'http://your-callback-url',],

           

接下來就準(zhǔn)備認(rèn)證用戶了!你會需要兩個(gè)路由:一個(gè)用于將用戶重定向至認(rèn)證提供網(wǎng)站,另一個(gè)用于認(rèn)證之后,從認(rèn)證服務(wù)接收回調(diào)。下面是一個(gè)使用 Socialize facade 的示例:

public function redirectToProvider(){
    return Socialize::with('github')->redirect();}public function handleProviderCallback(){
    $user = Socialize::with('github')->user();

    // $user->token;}

           

redirect 方法將用戶重定向到認(rèn)證 OAuth 的網(wǎng)站,而 user 方法會獲取返回的請求,以及從認(rèn)證網(wǎng)站取得的用戶信息。在重定向至用戶之前,你也可以設(shè)定請求的「 scopes 」:

return Socialize::with('github')->scopes(['scope1', 'scope2'])->redirect();

           

一旦你取得用戶實(shí)例,你能獲取到更多的用戶詳細(xì)信息:

獲取用戶資料

$user = Socialize::with('github')->user();// OAuth Two Providers$token = $user->token;// OAuth One Providers$token = $user->token;$tokenSecret = $user->tokenSecret;// All Providers$user->getId();$user->getNickname();$user->getName();$user->getEmail();$user->getAvatar();


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號