鍍金池/ 教程/ PHP/ 認(rèn)證
Laravel Cashier
Eloquent ORM
HTTP 響應(yīng)
發(fā)行說(shuō)明
擴(kuò)展包開(kāi)發(fā)
HTTP 控制器
事件
擴(kuò)展框架
Contracts
開(kāi)發(fā)
配置
表單驗(yàn)證
錯(cuò)誤與日志
Hashing
貢獻(xiàn)指南
郵件
Session
遷移與數(shù)據(jù)填充
查詢構(gòu)造器
Redis
升級(jí)向?qū)?/span>
概覽
緩存
服務(wù)提供者
Envoy 任務(wù)執(zhí)行器
隊(duì)列
單元測(cè)試
服務(wù)容器
文件系統(tǒng) / 云存儲(chǔ)
認(rèn)證
請(qǐng)求的生命周期
加密
模板
視圖 (View)
Laravel Homestead
Laravel 安裝指南
介紹
Command Bus
分頁(yè)
輔助方法
應(yīng)用程序結(jié)構(gòu)
HTTP 路由
HTTP 請(qǐng)求
基本用法
本地化
HTTP 中間件
結(jié)構(gòu)生成器
Facades
Laravel Elixir

認(rèn)證

介紹

Laravel 讓實(shí)現(xiàn)認(rèn)證機(jī)制變得非常簡(jiǎn)單。事實(shí)上,幾乎所有的設(shè)置默認(rèn)就已經(jīng)完成了。有關(guān)認(rèn)證的配置文件都放在 config/auth.php 里,而在這些文件里也都包含了良好的注釋描述每一個(gè)選項(xiàng)的所對(duì)應(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ù)庫(kù)結(jié)構(gòu)時(shí),密碼字段至少有60個(gè)字符寬度。同樣,在開(kāi)始之前,請(qǐng)先確認(rèn)您的 users (或其他同義) 數(shù)據(jù)庫(kù)表包含一個(gè)名為 remember_token 長(zhǎng)度為 100 的string類型、可接受 null 的字段。這個(gè)字段將會(huì)被用來(lái)儲(chǔ)存「記住我」的 session token。也可以通過(guò)在遷移文件中使用 $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 處理新的用戶注冊(cè)和「登陸」,而 PasswordController 可以幫助已經(jīng)注冊(cè)的用戶重置密碼。

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

用戶注冊(cè)

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

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

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

如果你不想使用預(yù)設(shè)的 AuthController,你需要直接使用 Laravel 的身份驗(yàn)證類來(lái)管理用戶認(rèn)證。別擔(dān)心,這也很簡(jiǎ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 方法可以接受由鍵值對(duì)組成的數(shù)組作為第一個(gè)參數(shù)。password 的值會(huì)先進(jìn)行哈希。數(shù)組中的其他 值會(huì)被用來(lái)查詢數(shù)據(jù)表里的用戶。所以,在上面的示例中,會(huì)根據(jù) email 列的值找出用戶。如果找到該用戶,會(huì)比對(duì)數(shù)據(jù)庫(kù)中存儲(chǔ)的哈希過(guò)的密碼以及數(shù)組中的哈希過(guò)后的 password值。假設(shè)兩個(gè)哈希后的密碼相同,會(huì)重新為用戶啟動(dòng)認(rèn)證通過(guò)的 session。

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

注意:在上面的示例中,并不一定要使用 email 字段,這只是作為示例。你應(yīng)該使用對(duì)應(yīng)到數(shù)據(jù)表中的「username」的任何鍵值。 intended 方法會(huì)重定向到用戶嘗試要訪問(wèn)的 URL , 其值會(huì)在進(jìn)行認(rèn)證過(guò)濾前被存起來(lái)。也可以給這個(gè)方法傳入一個(gè)預(yù)設(shè)的 URI,防止重定向的網(wǎng)址無(wú)法使用。

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

在認(rèn)證過(guò)程中,你可能會(huì)想要加入額外的認(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 列來(lái)儲(chǔ)存「記住我」的標(biāo)識(shí)。

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

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

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

以 ID 認(rèn)證用戶

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

Auth::loginUsingId(1);

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

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

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

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

你也可以使用 once 方法來(lái)讓用戶在單一請(qǐng)求內(nèi)登陸。不會(huì)有任何 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 事件 會(huì)被觸發(fā)。假設(shè)用戶嘗試認(rèn)證成功并且登陸了,auth.login 事件會(huì)被觸發(fā)。

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

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

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

<?php namespace App\Http\Controllers;

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)證過(guò)的用戶:

<?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)造方法,控制器的其他方法,或是其他可以通過(guò)服務(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ù)路由

路由中間件 只允許通過(guò)認(rèn)證的用戶訪問(wè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è)快速的方式來(lái)認(rèn)證用戶而不用特定設(shè)置一個(gè)「登入」頁(yè)。在您的路由內(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 中間件會(huì)使用用戶的 email 列當(dāng)做「 username 」。

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

你可能想要使用 HTTP 基本認(rèn)證,但不會(huì)在 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)證可能無(wú)法正常運(yùn)行。請(qǐng)?jiān)谀愕?.htaccess 文件內(nèi)新增以下代碼:

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

忘記密碼與重設(shè)

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

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

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

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

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

php artisan migrate

密碼重設(shè)控制器

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

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

protected $redirectTo = '/dashboard';

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

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

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

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

"laravel/socialite": "~2.0"

接下來(lái),在你的 config/app.php 配置文件中注冊(cè) Laravel\Socialite\SocialiteServiceProvider。也可以注冊(cè) facade:

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

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

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

接下來(lái)就準(zhǔn)備認(rèn)證用戶了!你會(huì)需要兩個(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 方法會(huì)獲取返回的請(qǐng)求,以及從認(rèn)證網(wǎng)站取得的用戶信息。在重定向至用戶之前,你也可以設(shè)定請(qǐng)求的「 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();
上一篇:擴(kuò)展框架下一篇:Session