服務(wù) ―― 用戶認(rèn)證

2018-02-24 15:38 更新

服務(wù) —— 用戶認(rèn)證

1、簡介

Laravel中實現(xiàn)用戶非常簡單。實際上,幾乎所有東西都已經(jīng)為你配置好了。配置文件位于config/auth.php,其中包含了用于調(diào)整認(rèn)證服務(wù)行為的、文檔友好的選項配置。

1.1 數(shù)據(jù)庫考量

默認(rèn)情況下,Laravel在app目錄下包含了一個Eloquent模型App\User,這個模型可以和默認(rèn)的Eloquent認(rèn)證驅(qū)動一起使用。如果你的應(yīng)用不使用Eloquent,你可以使用database認(rèn)證驅(qū)動,該驅(qū)動使用了Laravel查詢構(gòu)建器。

App\User模型構(gòu)建數(shù)據(jù)庫表結(jié)構(gòu)的時候,確保password字段長度至少有60位。

還有,你應(yīng)該驗證users表包含了可以為空的、字符串類型的remember_token字段長度為100,該字段用于存儲被應(yīng)用維護的”記住我(remember me)“的session令牌,這可以通過在遷移中使用$table->rememberToken();來實現(xiàn)。

2、用戶認(rèn)證快速入門

Laravel處理兩個認(rèn)證控制器,位于App\Http\Controllers\Auth和認(rèn)證,PasswordController`包含幫助用戶找回密碼的邏輯。每個控制器都使用trait來引入它們需要的方法。對很多應(yīng)用而言,你根本不需要修改這兩個控制器。

2.1?路由

默認(rèn)情況下,沒有路由將請求指向用戶認(rèn)證控制器,你要手動在app/Http/routes.php文件中添加它們:

// 認(rèn)證路由...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
// 注冊路由...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');

2.2 視圖

盡管框架包含了用戶認(rèn)證控制器,你還是需要提供這些控制器可以渲染的視圖。這些視圖位于resources/views/auth目錄,你可以按需自定義視圖是resources/views/auth/login.blade.php,注冊視圖是resources/views/auth/register.blade.php。

2.2.1 登錄表單示例

<!-- resources/views/auth/login.blade.php -->

<form method="POST" action="/auth/login">
    {!! csrf_field() !!}

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        Password
        <input type="password" name="password" id="password">
    </div>

    <div>
        <input type="checkbox" name="remember"> Remember Me
    </div>

    <div>
        <button type="submit">Login</button>
    </div>
</form>

2.2.2 注冊表單示例

<!-- resources/views/auth/register.blade.php -->

<form method="POST" action="/auth/register">
    {!! csrf_field() !!}

    <div>
        Name
        <input type="text" name="name" value="{{ old('name') }}">
    </div>

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        Password
        <input type="password" name="password">
    </div>

    <div>
        Confirm Password
        <input type="password" name="password_confirmation">
    </div>

    <div>
        <button type="submit">Register</button>
    </div>
</form>

2.3 認(rèn)證

既然你已經(jīng)為自帶的認(rèn)證控制器設(shè)置好了路由和視圖,接下來就準(zhǔn)備為應(yīng)用注冊新用戶并進行登錄認(rèn)證。你可以在瀏覽器中訪問定義好的路由,認(rèn)證控制器已經(jīng)實現(xiàn)了認(rèn)證已存在用戶以及存儲新用戶到數(shù)據(jù)庫中的業(yè)務(wù)邏輯(通過trait)。

當(dāng)一個用戶成功進行登錄認(rèn)證后,將會跳轉(zhuǎn)到/home鏈接,你需要事先注冊一個路由來處理該跳轉(zhuǎn)。你可以通過在AuthController中設(shè)置redirectPath屬性來自定義post認(rèn)證之后的跳轉(zhuǎn)路徑:

protected $redirectPath = '/dashboard';

當(dāng)一個用戶登錄認(rèn)證失敗后,將會跳轉(zhuǎn)到/auth/login鏈接。你可以通過定義AuthControllerloginPath屬性來自定義post認(rèn)證失敗后的跳轉(zhuǎn)路徑:

protected $loginPath = '/login';

2.3.1 自定義

要修改新用戶注冊所必需的表單字段,或者自定義新用戶字段如何存儲到數(shù)據(jù)庫,你可以修改AuthController類。該類負(fù)責(zé)為應(yīng)用驗證和創(chuàng)建新用戶。

AuthControllervalidator方法包含了新用戶的驗證規(guī)則,你可以隨意按需要自定義該方法。

AuthControllercreate方法負(fù)責(zé)使用Eloquent ORM在數(shù)據(jù)庫中創(chuàng)建新的App\User記錄。你可以基于自己的需要隨意自定義該方法。

2.4 獲取認(rèn)證用戶

你可以通過Auth門面訪問認(rèn)證用戶:

$user = Auth::user();

一旦用戶通過認(rèn)證后,你還可以通過Illuminate\Http\Request實例訪問認(rèn)證用戶:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class ProfileController extends Controller{
    /**
     * 更新用戶屬性.
     *
     * @param  Request  $request
     * @return Response
     */
    public function updateProfile(Request $request)
    {
        if ($request->user()) {
            // $request->user() 返回認(rèn)證用戶實例...
        }
    }
}

2.4.1 判斷當(dāng)前用戶是否通過認(rèn)證

要判斷某個用戶是否登錄到應(yīng)用,可以使用Auth門面check方法,如果用戶通過認(rèn)證則返回true

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

此外,你還可以在用戶訪問特定路由/控制器之前使用中間件來驗證用戶是否通過認(rèn)證,想要了解更多,可以查看路由保護文檔。

2.5 路由保護

路由中間件可用于只允許通過認(rèn)證的用戶訪問給定路由。Laravel通過定義在app\Http\Middleware\Authenticate.phpauth中間件來處理這一操作。你所要做的僅僅是將該中間件加到相應(yīng)的路由定義中:

// 使用路由閉包...
Route::get('profile', ['middleware' => 'auth', function() {
    // 只有認(rèn)證用戶可以進入...
}]);
// 使用控制器...
Route::get('profile', [
    'middleware' => 'auth',
    'uses' => 'ProfileController@show'
]);

當(dāng)然,如果你正在使用控制器類,也可以在控制器的構(gòu)造方法中調(diào)用middleware方法而不是在路由器中直接定義:

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

2.6 登錄失敗次數(shù)限制

如果你正在使用Laravel內(nèi)置的AuthController類,Illuminate\Foundation\Auth\ThrottlesLogins?trait 可以用于限制用戶登錄失敗次數(shù)。默認(rèn)情況下,用戶在幾次登錄失敗后將在一分鐘內(nèi)不能登錄,這種限制基于用戶的用戶名/郵箱地址+IP地址:

<?php

namespace App\Http\Controllers\Auth;

use App\User;use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

class AuthController extends Controller{
    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    // AuthController類的其它部分...
}

3、手動認(rèn)證用戶

當(dāng)然,你也可以不使用Laravel自帶的認(rèn)證控制器。如果你選擇移除這些控制器,你需要直接使用Laravel認(rèn)證類來管理用戶認(rèn)證。別擔(dān)心,這很簡單!

我們將會通過Auth門面來訪問認(rèn)證服務(wù),因此我們需要確保在類的頂部導(dǎo)入了Auth門面,讓我們看看attempt方法:

<?php

namespace App\Http\Controllers;

use Auth;
use Illuminate\Routing\Controller;

class AuthController extends Controller{
    /**
     * 處理登錄認(rèn)證
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password])) {
            // 認(rèn)證通過...
            return redirect()->intended('dashboard');
        }
    }
}

attempt方法接收鍵值數(shù)組對作為第一個參數(shù),數(shù)組中的值被用于從數(shù)據(jù)表中查找用戶,因此,在上面的例子中,用戶將會通過email的值獲取,如果用戶被找到,經(jīng)哈希運算后存儲在數(shù)據(jù)中的密碼將會和傳遞過來的經(jīng)哈希運算處理的密碼值進行比較。如果兩個經(jīng)哈希運算的密碼相匹配那么一個認(rèn)證session將會為這個用戶開啟。

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

重定向器上的intended方法將會將用戶重定向到登錄之前用戶想要訪問的URL,在目標(biāo)URL無效的情況下備用URI將會傳遞給該方法。

如果你想的話,除了用戶郵件和密碼之外還可以在認(rèn)證查詢時添加額外的條件,例如,我們可以驗證被標(biāo)記為有效的用戶:

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

要退出應(yīng)用,可以使用Auth門面的logout方法,這將會清除用戶session中的認(rèn)證信息:

Auth::logout();

注意:在這些例子中,email并不是必須選項,在這里只不過是作為一個例子。你可以在自己的數(shù)據(jù)庫使用任何其他與“用戶名”相對應(yīng)的字段。

3.1 記住用戶

如果你想要在應(yīng)用中提供“記住我”的功能,可以傳遞一個布爾值作為第二個參數(shù)到attempt方法,這樣用戶登錄認(rèn)證狀態(tài)就會一直保持直到他們手動退出。當(dāng)然,你的users表必須包含remember_token字段,該字段用于存儲“記住我”令牌。

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

如果你要“記住”用戶,可以使用viaRemember方法來判斷用戶是否使用“記住我”cookie進行認(rèn)證:

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

3.2 其它認(rèn)證方法

3.2.1 認(rèn)證用戶實例

如果你需要將一個已存在的用戶實例登錄到應(yīng)用中,可以調(diào)用用戶實例上的login方法,給定實例必須是Illuminate\Contracts\Auth\Authenticatable契約的實現(xiàn),當(dāng)然,Laravel自帶的App\User模型已經(jīng)實現(xiàn)了該接口:

Auth::login($user);

3.2.2 通過ID認(rèn)證用戶

要通過用戶ID登錄到應(yīng)用,可以使用loginUsingId方法,該方法接收你想要認(rèn)證用戶的主鍵作為參數(shù):

Auth::loginUsingId(1);

3.2.3 一次性認(rèn)證用戶

你可以使用once方法只在單個請求中將用戶登錄到應(yīng)用,而不存儲任何session和cookie,這在構(gòu)建無狀態(tài)的API時很有用。once方法和attempt方法用法差不多:

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

4、基于HTTP的基本認(rèn)證

HTTP基本認(rèn)證能夠幫助用戶快速實現(xiàn)登錄認(rèn)證而不用設(shè)置專門的登錄頁面,首先要在路由中加上auth.basic中間件。該中間件是Laravel自帶的,所以不需要自己定義:

Route::get('profile', ['middleware' => 'auth.basic', function() {
    // 只有認(rèn)證用戶可以進入...
}]);

中間件加到路由中后,當(dāng)在瀏覽器中訪問該路由時,會自動提示需要認(rèn)證信息,默認(rèn)情況下,auth.basic中間件使用用戶記錄上的email字段作為“用戶名”。

FastCGI上注意點

如果你使用PHP FastCGI,HTTP基本認(rèn)證將不能正常工作,需要在.htaccess文件加入如下內(nèi)容:

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

4.1 無狀態(tài)的HTTP基本認(rèn)證

使用HTTP基本認(rèn)證也不需要在session中設(shè)置用戶標(biāo)識cookie,這在API認(rèn)證中非常有用。要實現(xiàn)這個,需要定義一個調(diào)用onceBasic方法的中間件。如果該方法沒有返回任何響應(yīng),那么請求會繼續(xù)走下去:

<?php

namespace Illuminate\Auth\Middleware;

use Auth;
use Closure;

class AuthenticateOnceWithBasicAuth{
    /**
     * 處理輸入請求.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return Auth::onceBasic() ?: $next($request);
    }

}

接下來,注冊路由中間件并將其添加到路由中:

Route::get('api/user', ['middleware' => 'auth.basic.once', function() {
    // 只有認(rèn)證用戶可以進入...
}]);

5、重置密碼

5.1?數(shù)據(jù)庫考量

大多數(shù)web應(yīng)用提供了用戶重置密碼的功能,Laravel提供了便利方法用于發(fā)送密碼提示及執(zhí)行密碼重置而不需要你在每個應(yīng)用中重新實現(xiàn)。

開始之前,先驗證App\User模型實現(xiàn)了Illuminate\Contracts\Auth\CanResetPassword契約。當(dāng)然,Laravel自帶的App\User模型已經(jīng)實現(xiàn)了該接口,并使用Illuminate\Auth\Passwords\CanResetPassword?trait來包含實現(xiàn)該接口需要的方法。

5.1.1 生成重置令牌表遷移

接下來,用來存儲密碼重置令牌的表必須被創(chuàng)建,Laravel已經(jīng)自帶了這張表的遷移,就存放在database/migrations目錄。所有,你所要做的僅僅是運行遷移:

php artisan migrate

5.2 路由

Laravel自帶了Auth\PasswordController,其中包含重置用戶必須的邏輯。然而,你需要定義一個路由將請求轉(zhuǎn)發(fā)到該控制器:

// 密碼重置鏈接請求路由...
Route::get('password/email', 'Auth\PasswordController@getEmail');
Route::post('password/email', 'Auth\PasswordController@postEmail');
// 密碼重置路由...
Route::get('password/reset/{token}', 'Auth\PasswordController@getReset');
Route::post('password/reset', 'Auth\PasswordController@postReset');

5.3 視圖

除了為Auth\PasswordController定義路由之外,還需要提供相應(yīng)視圖,別擔(dān)心,我們將會提供示例視圖來幫助你開始,當(dāng)然,你也可以自定義表單樣式。

5.3.1 密碼重置鏈接請求表單示例

你需要為密碼重置請求表單 提供HTML視圖,該視圖文件應(yīng)該放在resources/views/auth/password.blade.php,表單提供了一個輸入用戶郵箱地址的字段,從而允許用戶從郵件中訪問密碼重置鏈接:

<!-- resources/views/auth/password.blade.php -->

<form method="POST" action="/password/email">
    {!! csrf_field() !!}

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        <button type="submit">
            Send Password Reset Link
        </button>
    </div>
</form>

當(dāng)一個用戶提交了重置密碼請求后,將會收到一封電子郵件,其中包含了一個鏈接,該鏈接指向PasswordControllergetReset方法,你需要為該電子郵件創(chuàng)建一個視圖resources/views/emails/password.blade.php。該視圖將會獲取包含密碼重置令牌的$token變量,用于和用戶重置密碼請求進行匹配。下面是一個電子郵件視圖的例子:

<!-- resources/views/emails/password.blade.php -->
Click here to reset your password: {{ url('password/reset/'.$token) }}

5.3.2 密碼重置表單示例

當(dāng)用戶點擊電子郵件中的鏈接來重置密碼時,需要提交一個密碼重置表單,該視圖位于resources/views/auth/reset.blade.php

下面是一個密碼重置表單示例:

<!-- resources/views/auth/reset.blade.php -->

<form method="POST" action="/password/reset">
    {!! csrf_field() !!}
    <input type="hidden" name="token" value="{{ $token }}">

    <div>
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        <input type="password" name="password">
    </div>

    <div>
        <input type="password" name="password_confirmation">
    </div>

    <div>
        <button type="submit">
            Reset Password
        </button>
    </div>
</form>

5.4 重置密碼后

如果你已經(jīng)定義好路由和視圖來重置用戶密碼,只需要在瀏覽器中訪問這些路由即可??蚣茏詭У?code>PasswordController已經(jīng)包含了發(fā)送密碼重置鏈接郵件以及更新數(shù)據(jù)庫中密碼的邏輯。

密碼被重置后,用戶將會自動登錄到應(yīng)用并重定向到/home。你可以通過定義上PasswordControllerredirectTo屬性來自定義post密碼重置跳轉(zhuǎn)鏈接:

protected $redirectTo = '/dashboard';

注意:默認(rèn)情況下,密碼重置令牌一小時內(nèi)有效,你可以通過修改config/auth.php文件中的選項reminder.expire來改變有效時間。

6、社會化登錄認(rèn)證

Laravel中還可以使用Laravel Socialite通過OAuth提供者進行簡單、方便的認(rèn)證,也就是社會化登錄,目前支持使用Facebook、Twitter、LinkedIn、GitHub和Bitbucket進行登錄認(rèn)證。

要使用社會化登錄,需要在composer.json文件中添加依賴:

composer require laravel/socialite

6.1 配置

安裝完社會化登錄庫后,在配置文件config/app.php中注冊Laravel\Socialite\SocialiteServiceProvider

'providers' => [
    // 其它服務(wù)提供者...
    Laravel\Socialite\SocialiteServiceProvider::class,
],

還要在app配置文件中添加Socialite門面到aliases數(shù)組:

'Socialite' => Laravel\Socialite\Facades\Socialite::class,

你還需要為應(yīng)用使用的OAuth服務(wù)添加認(rèn)證信息,這些認(rèn)證信息位于配置文件config/services.php,而且鍵為facebook,?twitter,linkedin,?google,?githubbitbucket,這取決于應(yīng)用需要的提供者。例如:

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

6.2 基本使用

接下來,準(zhǔn)備好認(rèn)證用戶!你需要兩個路由:一個用于重定向用戶到OAuth提供者,另一個用戶獲取認(rèn)證后來自提供者的回調(diào)。我們使用Socialite門面訪問Socialite?:

<?php

namespace App\Http\Controllers;

use Socialite;
use Illuminate\Routing\Controller;

class AuthController extends Controller{
    /**
     * 將用戶重定向到GitHub認(rèn)證頁面.
     *
     * @return Response
     */
    public function redirectToProvider()
    {
        return Socialite::driver('github')->redirect();
    }

    /**
     * 從GitHub獲取用戶信息.
     *
     * @return Response
     */
    public function handleProviderCallback()
    {
        $user = Socialite::driver('github')->user();

        // $user->token;
    }
}

redirect方法將用戶發(fā)送到OAuth提供者,user方法讀取請求信息并從提供者中獲取用戶信息,在重定向用戶之前,你還可以在請求上使用scope方法設(shè)置”作用域”,該方法將會重寫已存在的所有作用域:

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

當(dāng)然,你需要定義路由到控制器方法:

 Route::get('auth/github', 'Auth\AuthController@redirectToProvider');
 Route::get('auth/github/callback', 'Auth\AuthController@handleProviderCallback');

6.2.1 獲取用戶信息

有了用戶實例之后,可以獲取用戶的更多詳情:

$user = Socialite::driver('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();

7、添加自定義認(rèn)證驅(qū)動

如果你沒有使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫存儲用戶信息,你需要使用自己的認(rèn)證驅(qū)動擴展Laravel。我們使用Auth門面上的extend方法來定義自定義的驅(qū)動,你需要在服務(wù)提供者調(diào)用extend方法:

<?php

namespace App\Providers;

use Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Support\ServiceProvider;

class AuthServiceProvider extends ServiceProvider{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Auth::extend('riak', function($app) {
            // 返回Illuminate\Contracts\Auth\UserProvider實例...
            return new RiakUserProvider($app['riak.connection']);
        });
    }

    /**
     * 在容器中注冊綁定.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

通過extend方法注冊驅(qū)動后,你可以在配置文件config/auth.php中切換到新的驅(qū)動。

7.1 UserProvider契約

Illuminate\Contracts\Auth\UserProvider實現(xiàn)只負(fù)責(zé)從持久化存儲系統(tǒng)中獲取Illuminate\Contracts\Auth\Authenticatable實現(xiàn),例如MySQL、Riak等等。這兩個接口允許Laravel認(rèn)證機制繼續(xù)起作用而不管用戶數(shù)據(jù)如何存儲或者何種類來展現(xiàn)。

讓我們先看看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方法通常獲取一個代表用戶的鍵,例如MySQL數(shù)據(jù)中的自增ID。該方法獲取并返回匹配該ID的Authenticatabl實現(xiàn)。

retrieveByToken函數(shù)通過唯一標(biāo)識和存儲在remember_token字段中的“記住我”令牌獲取用戶。和上一個方法一樣,該方法也返回Authenticatabl實現(xiàn)。

updateRememberToken方法使用新的$token更新$userremember_token字段,新令牌可以是新生成的令牌(在登錄是選擇“記住我”被成功賦值)或者null(用戶退出)。

retrieveByCredentials方法在嘗試登錄系統(tǒng)時獲取傳遞給Auth::attempt方法的認(rèn)證信息數(shù)組。該方法接下來去底層持久化存儲系統(tǒng)查詢與認(rèn)證信息匹配的用戶,通常,該方法運行一個帶“where”條件($credentials[‘username’])的查詢。然后該方法返回UserInterface的實現(xiàn)。這個方法不做任何密碼校驗和認(rèn)證。

validateCredentials方法比較給定$user$credentials來認(rèn)證用戶。例如,這個方法比較$user->getAuthPassword()字符串和經(jīng)Hash::make處理的$credentials['password']。這個方法只驗證用戶認(rèn)證信息并返回布爾值。

7.2?Authenticatable契約

既然我們已經(jīng)探索了UserProvider上的每一個方法,接下來讓我們看看Authenticatable。該提供者應(yīng)該從retrieveByIdretrieveByCredentials方法中返回接口實現(xiàn):

<?php

namespace Illuminate\Contracts\Auth;

interface Authenticatable {

    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();

}

這個接口很簡單,getAuthIdentifier方法返回用戶“主鍵”,在MySQL后臺中是ID,getAuthPassword返回經(jīng)哈希處理的用戶密碼,這個接口允許認(rèn)證系統(tǒng)處理任何用戶類,不管是你使用的是ORM還是存儲抽象層。默認(rèn)情況下,Laravel自帶的app目錄下的User類實現(xiàn)了這個接口,所以你可以將這個類作為實現(xiàn)例子。

擴展閱讀1:實例教程 —— 使用Laravel內(nèi)置組件快速實現(xiàn)注冊登錄
擴展閱讀2:實例教程 —— 使用Laravel內(nèi)置組件快速實現(xiàn)密碼重置
擴展閱讀3:實例教程 —— 使用Socialite實現(xiàn)GitHub登錄認(rèn)證

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號