转载自 Laravel 论坛:https://learnku.com/laravel/t...

Laravel领有一个很棒的现成的用户认证零碎,当然咱们也须要在在某些中央自定义一些配置。对于某些自定义配置,咱们并不需要再去寻找一个扩大包或者写一大堆代码。让咱们来钻研一下这套认证零碎背地暗藏着哪些乏味的性能。

技巧 1. Auth::routes() 参数

咱们应该都晓得办法 Auth::routes() 来自于 Laravel UI package (在Laravel 7之前, 它被蕴含在内核中)。

但你晓得它能够承受一个数组来启用/禁用特定的认证路由吗?

对于Laravel 7,上面是可用的参数及其默认值:

Auth::routes([    'login'    => true,     'logout'   => true,     'register' => true,     'reset'    => true,   // 用于重置明码    'confirm'  => false,  // 用于额定的明码确认    'verify'   => false,  // 用于邮箱认证]);

这些参数仅启用或禁用某些路由。

要理解它们是如何工作的,能够查看文件Laravel UI中的AuthRouteMethods:

return function ($options = []) {    // 登录路由...    if ($options['login'] ?? true) {        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');        $this->post('login', 'Auth\LoginController@login');    }    // 登前途由...    if ($options['logout'] ?? true) {        $this->post('logout', 'Auth\LoginController@logout')->name('logout');    }    // 注册路由...    if ($options['register'] ?? true) {        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');        $this->post('register', 'Auth\RegisterController@register');    }    // 明码重设路由...    if ($options['reset'] ?? true) {        $this->resetPassword();    }    // 明码确认路由...    if ($options['confirm'] ??        class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {        $this->confirmPassword();    }    // 邮箱验证路由...    if ($options['verify'] ?? false) {        $this->emailVerification();    }};

技巧 2. Laravel UI: 仅生成控制器

官网文档指定了应用 Laravel UI 的次要办法:

php artisan ui vue --auth

然而,如果您不须要可视 UI,该怎么办?如果您创立的是一个仅基于 API 的我的项目,且在框架中没有任何前端呢?

您依然能够应用 Laravel Auth 及其控制器。装置 Laravel UI 并运行以下命令:

php artisan ui:controllers

 它只会生成 app/Http/Controllers/Auth , 因而您不须要 Blade 或 Vue 文件即可应用它们。

请在 Github 存储库 中参阅这个 Artisan 命令的实现。


技巧 3. 对敏感操作从新认证明码

您是否已经保护过 Github 存储库,并试图更改其拜访设置?而后,Github 要求您再次输出明码,以确保的确是您在操作。

从 Laravel 6.2 开始,框架中也集成了该性能。

您只须要向要爱护的路由增加一个名为password.confirm的中间件即可。

Route::get('/secrets', 'SecretsController@show')->middleware('password.confirm');

Dries Vints 援用自官网性能公布文章:

如果尝试拜访该路由,将提醒您确认明码,和在 GitHub 等其余应用程序上看到的一样。

确认明码后,默认状况下会在用户会话中存储一个工夫戳。工夫戳继续3个小时,因而用户在此期间不用再次输出明码。

您能够应用auth配置文件中的password_timeout配置选项来自定义此持续时间。


技巧 4. 登记其余设施

从 Laravel 5.6 起,咱们提供了一种独自的办法来主动登记应用咱们的帐户登录的任何其余设施或浏览器:

Auth::logoutOtherDevices($password); 

典型的用法是在以后设施胜利登录后登记其余设施。为此,咱们从 TraitAuthenticatesUsers.php中重写办法authenticated(),并将其放入app / Http / Controllers / Auth / LoginController.php中:

protected function authenticated(Request $request, $user){    \Auth::logoutOtherDevices(request('password'));}

另外,不要遗记激活app / Http / Kernel.php文件中的中间件AuthenticateSession,默认状况下该中间件已被正文:

protected $middlewareGroups = [    'web' => [        \App\Http\Middleware\EncryptCookies::class,        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,        \Illuminate\Session\Middleware\StartSession::class,        // \Illuminate\Session\Middleware\AuthenticateSession::class,        \Illuminate\View\Middleware\ShareErrorsFromSession::class,        \App\Http\Middleware\VerifyCsrfToken::class,        \Illuminate\Routing\Middleware\SubstituteBindings::class,    ],

登录/注册后的重定向:自定义逻辑

默认状况下,Laravel 的 LoginController 和 RegisterController 具备雷同的属性:

class RegisterController extends Controller{    protected $redirectTo = RouteServiceProvider::HOME;

因而,您能够指定胜利登录/注册后重定向到的 URL。默认值在 app/Providers/RouteServiceProvider.php中:

class RouteServiceProvider extends ServiceProvider{    public const HOME = '/home';

如何自定义它?

首先,您能够别离为登录和注册控制器的$redirectTo属性指定其余值。

然而,如果您具备更简单的动静重定向逻辑,例如须要依据用户角色来判断呢?

您能够在身份验证控制器中创立一个redirectTo()办法,而后在其中指定条件。该办法将笼罩$ redirectTo属性的任何值。

参见示例:

class RegisterController extends Controller{    protected $redirectTo = RouteServiceProvider::HOME;    protected function redirectTo()    {        if (auth()->user()->role_id == 1) {            return '/admin';        }        return '/home';    }

技巧 5. 疾速创立新用户

如果您须要创立一个新用户,但还没有筹备好注册页面该怎么办?

只需在您的终端中关上 Laravel Tinker

php artisan tinker

如果您不相熟 Tinker,须要晓得它是可能执行任何 Laravel / PHP 代码的命令行工具。因而,在其中,您能够轻松创立用户,键入此 Eloquent 命令并按 Enter:

\App\User::create(['name' => 'Admin', 'email' => 'admin@admin.com', 'password' => bcrypt('somesecurepassword')]);

然而,如果您须要创立许多用户进行测试,例如10、100或1000,该怎么办?没问题,咱们能够在database / factories / UserFactory.php中应用 Laravel 默认提供的 Factory 类:

$factory->define(User::class, function (Faker $faker) {    return [        'name' => $faker->name,        'email' => $faker->unique()->safeEmail,        'email_verified_at' => now(),        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // 明码        'remember_token' => Str::random(10),    ];});

这些是咱们创立的“假”用户的默认值。为此,咱们将生成一个 Seeder 文件:

php artisan make:seeder UsersSeeder

而后,咱们关上生成的文件database / seeds / UsersSeeder.php,并用以下代码填充run()办法:

public function run(){    // This will create 100 users    factory(App\User::class, 100)->create(); }

要运行它,咱们须要执行以下命令:

php artisan db:seed --class=UsersSeeder

您能够在Laravel官网文档中理解更多无关数据库种子的信息。


Tip 6. 应用邮箱和/或用户名登录

默认状况下,Laravel用户应用邮箱明码进行身份验证。然而,如果您的用户标识不应用邮箱怎么办?例如,应用用户名作为标识。

您能够通过笼罩 traitAuthenticatesUsers.php中的一种办法来轻松更改它。

这是默认值:

trait AuthenticatesUsers{    // ... 其余办法    public function username()    {        return 'email';    }

您能够将其复制到您的LoginController.php中,只需更改值即可:

class LoginController extends Controller{    use AuthenticatesUsers;    // ... 其余办法    public function username()    {        return 'username';    }}

让咱们更进一步。如果您想让用户能够应用邮箱或用户名登录怎么办?这样的话,用户能够在“邮箱/用户名”字段中抉择其中一个填写。

让咱们向下面的username()办法增加一个判断。咱们查看输出的字符串是否是电子邮件,若不是,则将其视为用户名。这是一个 PHP 函数,甚至不是 Laravel 函数。

class LoginController extends Controller{    // ...    public function username()    {        return filter_var(request('email'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';    }}
留神: 别忘了把登录表单的  input type="email" 改成 type="text"

Tip 7.登录申请频繁:自定义参数

如果您尝试在同一分钟内应用有效凭据登录五次以上,则申请会被拦挡,并显示一条音讯尝试登录的次数过多。 请在X秒后重试。

该拦挡操作将继续1分钟,并且对于用户的用户名/电子邮件及其IP地址是惟一的。

您能够自定义这些参数:

  • 一分钟内的有效尝试次数(默认为五次尝试)
  • 阻止登录的分钟数(默认为1分钟)

这两个参数在TraitThrottlesLogins外部:

trait ThrottlesLogins{    // ... other methods    /**     * Get the maximum number of attempts to allow.     *     * @return int     */    public function maxAttempts()    {        return property_exists($this, 'maxAttempts') ? $this->maxAttempts : 5;    }    /**     * Get the number of minutes to throttle for.     *     * @return int     */    public function decayMinutes()    {        return property_exists($this, 'decayMinutes') ? $this->decayMinutes : 1;    }}

因而,要笼罩这些属性,能够在 LoginController 外部指定属性:

class LoginController extends Controller{    protected $maxAttempts = 3;  // Default is 5    protected $decayMinutes = 2; // Default is 1    // ...}

Tip 8. 注册: 禁用主动登录

默认状况下,新注册的用户将主动登录并重定向到主页。

如果您须要禁用该性能并改为显示注册胜利页面,而不主动登录的话,能够执行以下操作。

原始注册办法位于 Trait RegistersUsers 的外部:

trait RegistersUsers{    public function register(Request $request)    {        $this->validator($request->all())->validate();        event(new Registered($user = $this->create($request->all())));        $this->guard()->login($user);        if ($response = $this->registered($request, $user)) {            return $response;        }        return $request->wantsJson()                    ? new Response('', 201)                    : redirect($this->redirectPath());    }

因而,您的指标是在RegisterController中笼罩它,而后重定向到新页面,而不是登录:

class RegisterController extends Controller{    use RegistersUsers;    public function register(Request $request)    {        $this->validator($request->all())->validate();        event(new Registered($user = $this->create($request->all())));        return redirect()->route('your_success_page_route_name');    }

Tip 9. 登录: 通过电子邮件/明码进行附加查看

如果除了默认的电子邮件和明码外,还须要进行其余查看,该怎么办? 例如,您要检查用户是否处于活动状态或未被禁止。

您能够增加额定的字段 credentials 到定义在 AuthenticatesUsers trait 的鉴权数组中:

trait AuthenticatesUsers{    // ...    protected function credentials(Request $request)    {        return $request->only($this->username(), 'password');    }

而后只须要重写 LoginController 即可:

class LoginController extends Controller{    // ...    protected function credentials(Request $request)    {        return $request->only($this->username(), 'password') + ['is_active' => 1];    }
留神: 这是一个很乏味的便捷提醒,然而我建议您在独自的中间件中执行这种额定的查看,而后向用户提供更明确的谬误音讯,而不是默认的凭证谬误。

就是这些,都是一些便捷提醒,然而自定义代码和内部扩大包还有很多能够施展的中央。 因而,能够持续关注无关该主题的更多文章!

探讨请返回业余的 Laravel 论坛:https://learnku.com/laravel/t...