Bootstraplaravel 基础教程 —— 认证

简介

laravel
使执行认证的变得分外简单,事实上,它提供了分外周到的部署项以适应应用的事情。认证的布局文件存放在
config/auth.php
目录,这里的各类选项都提供了包罗万象的诠释文档,你可以从这边调整认证服务的行为。

在 laravel 中,认证服务的主干是由 guards(守卫)
providers(供应商)
组成。守卫定义了从呼吁中表达用户的章程,比如说,laravel 自带了 session
守卫和 token 守卫,session 守卫是从所蕴藏的对话及 cookies
中去评释请求中的用户的,而 token 守卫则是从请求中的 API token
举办用户认证的。

供应商则定义了从持久化存储中得到用户的法门。laravel 自身提供了
Eloquentdatabase
查询构造器二种检索模式。当然,你也可以添加额外的供应商去做这个。

设若那听起来有点混乱,请不要操心。大多数的应用程序是有史以来不需要修改认证服务的默认配置音信的。

数据库注意事项

默认的,laravel 在 app 目录下富含了 App\User Eloquent
模型。该模型使用了默认的 Eloquent 认证驱动。假设你的使用不是行使
Eloquent 驱动,你可以利用 database 认证驱动,database 认证驱动是依据laravel 的询问构造器的。

当你为 App\User 模型去构建数据库表结构时,你应有认可密码应该保障最少
60 个字符的长度,默认的 255 是一个相比较好的拔取。

除此以外,你需要保证 users 表中隐含了一个足以为 null 的字符串列
remember_token,它应当有着 100
个字符的长短。这么些字段是用来存储用户保持长久登录的 token
值的。你可以在搬迁中采用 $table->rememberToken() 来飞速的充裕该列。

快捷先河

laravel 装载了六个用来拓展验证的控制器,它们存储在
App\Http\Controllers\Auth 命名空间下。AuthController
用来处理用户注册及注脚的逻辑,而 PasswordController
包含了用户找回密码的有关逻辑。它们每个控制器都是通过引入 trait
来含有他们所急需的格局。对于大多数应用来说,你是完全没有必要去修改这多少个控制器的。

路由

laravel 提供了一个快速的主意来扭转认证的路由和视图的脚手架,你可以使用
artisan 命令:

php artisan make:auth

在一个新的选取中,这一个命令会用来拓展安装注册和登录的视图,也会注入所有的求证相关的路由。HomeController
也会被转移。这些控制器提供了 post
登录请求的拍卖措施。你也足以依据自己的急需删除或修改这么些控制器。

视图

就如上边所涉嫌的,php artisan make:auth
命令会制造所有认证相关的视图,并且保留在 resources/views/auth 目录下。

make:auth 命令也会创制 resoucres/views/layouts
目录,并在该目录下为使用创设了一个主导的布局。所有的这个视图都是拔取了
Bootstrap CSS 框架,你可以依照本人的急需去定制化修改。

举行表达

今昔你已经具备了印证相关的控制器、路由和视图,你的行使已经怀有了挂号和认证的力量。你能够通过浏览器访问你的使用,认证控制器已经包含了具备的证实用户和存储用户到数据库的章程(通过
traits)。

自定义重定向地址

当用户通过认证后会被重定向到 / URL。你可以因而在 AuthController
控制器中定义 redirectTo 属性来修改重定向地址:

protected $rediredtTo = '/home';

当用户并未表明成功,它会重定向回登录地址。

自定义守卫

你也可以定制化 guard 用来注解用户。你需要在 AuthController 中定义
guard 属性。它的值应该是与您的 auth.php 配置中的某一个 guards
值相匹配的:

protected $guard = 'admin';

自定义 验证/存储

您恐怕会想要在用户注册时存储一些其他必要的表单字段,进而将猛增用户的信息囤积到数据库中,这些时候你就需要修改
AuthController 类了,这多少个类主管用户的创设和表单的求证。

AuthController 类中采取 validate
方法来证实验证表单与认证规则的配合程度。你可以按照自身的内需来修改这么些主意。

AuthController 类中行使 create
方法用来在数据库中新增一条用户的记录。那里运用了 Eloquent
ORM。你可以依照本人的需求修改这些办法。

得到已证实的用户

你可以经过 Auth 假面来走访已经表达的用户:

$user = Auth::user();

其余,一旦用户通过证实,你可以经过 Illuminate\Http\Request
的实例来访问经过证实后的用户。你应当记得,类型提醒的类会被电动的注入到你的控制器方法中:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

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

看清当前用户是否已被表明

您可以经过 Auth 假面的 check
方法来判定当前用户是否已经被注明。虽然该用户已经被证实则会回来 true:

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

您应该接纳中间件来过滤未被注解的用户访问一些路由或控制器。

珍贵路由

路由中间件可以被用来限制只有已经被证实的用户才能访问所给定的路由。laravel
自带了 auth 中间件,该中间件被定义在
app\Http\Middleware\Authenticate.php
文件中。你只需要在定义路由时增大上该中间件就足以了:

// Using A Route Closure...

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

// Using A Controller...

Route::get('profile', [
  'middleware' => 'auth',
  'uses' => 'ProfileController@show'
]);

自然,如果您采用控制器来注册路由,你可以在控制器的构造函数中接纳
middleware 方法来附加中间件:

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

指定守卫

当你附加 auth 中间件到路由时,你也能够指定采取哪位守卫去提供验证:

Route::get('profile', [
  'middleware' => 'auth:api',
  'uses' => 'ProfileController@show'
]);

所指定的看守应该与安排文件 auth.php 中的 guards 数组键之一相匹配。

表达节流

假诺您利用了 laravel 內建的 AuthController 类,那么
Illuminate\Foundation\Auth\ThrottlesLogins trait
可以被用来限制用户尝试登陆的次数。默认的,当用户举行登陆数次失败时,其将会在一分钟内无法进展登陆。节流是基于用户的
username / e-mail 和 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;

  // Rest of AuthController class...
}

手动举行用户认证

理所当然,你未曾必要肯定使用 laravel
內建的注脚控制器。虽然您采取删除这一个验证控制器,那么你需要直接的利用
laravel 认证类来治本用户的印证。别担心,这当然不在话下。

我们将经过 Auth 假面来走访 laravel
的注解服务,所以,大家要保管在类公事的顶部引入 Auth
假面。接着,让我们查阅一下 attempt 方法:

<?php

namespace App\Http\Controllers;

use Auth;

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

attempt
方法接收一个键值对数组来作为第一个参数。数组中的值用来在数据库中找寻相匹配的用户。所以,在下边的事例中,会回来匹配到
email 列为 $email
的用户。假使用户被找到,存储在数据库中的哈希后的密码会和数组中经过哈希加密的
password
值举办匹配。假使多个哈希后的值优异成功的话,就会张开一个该用户已经证实的对话。

比方证实成功,则 attempt 方法会重返 true。否则重临 false

intended 方法用来回到给重定向器用户在报到前所想要前往的 URL
地址,该办法也吸收一个参数作为所请求地址不可用时的备用地址。

点名额外的表明音讯

尽管您需要,你也足以扩大部分相当条件做讲明查询,比如,你需要证实被标记为
‘active’ 的用户:

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

小心,在上头的例子中 email
并不是必要的选项,这仅仅只是作为一个演示。你可以使用其他进展用户认证的凭据来映射数据库中的字段。

走访指定的守护实例

你可以运用 Auth 假面的 guard
方法来赢得你所急需的看守实例。这使你可以在同一个应用中管理多种表达模型或用户表,并落实独立的验证。

guard 方法中所传递的防卫名称应当与部署文件 auth.php 中 guards
之一相匹配:

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

登出

您可以采用 Auth 假面的 logout
方法来进展用户的淡出,该措施将解除用户认证的对话消息:

Auth::logout();

难忘用户

设若你想要在您的采用中提供 记住我 的功能,你只需要在 attempt
方法中传递一个布尔值作为第二个参数,这将保持用户的印证音讯直到用户手动的淡出登录。当然,这要求你的用户表中必须含有
remember_token 列:

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

假定您作为被铭记的用户登录的,那么您可以动用 viaRemember
方法来判断用户的证实是不是透过 记住我 的 cookie:

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

其他认证方法

经过用户实例进行求证

假若您需要在利用中著录一个曾经存在的用户实例,你可以行使 login
方法。所给定的参数必须是促成了
Illuminate\Contracts\Auth\Authenticatable 契约的一个实例。当然,在
laravel 中 App\User 模型已经实现了那些接口:

Auth::login($user);

自然,你也可以指定守卫实例:

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

通过用户ID直接证实

你能够采纳 loginUseingId 方法来经过 ID
记录用户的音讯,该方法简便的吸纳一个急需开展求证的用户的主键:

Auth::loginUsingId(1);

仅认证用户五遍

once 方法只在时下央浼中进行用户认证。不会储存会话或
cookies。这对构建无状态的 API 很有帮忙。once 方法和 attempt
具有同样的签证模式:

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

基于 HTTP 的认证

依照 HTTP
的验证提供了高速的用户认证机制而不用设立专门的报到页面。为了起先,你应有附加
auth.basic 中间件到你的路由。laravel 中內建了 auth.basic
中间件,所以您不需要去定义它:

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

设若该中间件被增大到路由中,你每趟访问该路由时都会被唤起要求验证消息。默认的,auth.basic
中间件使用 email 列作为用户记录的用户名。

FastCGI 提示

假若你使用 PHP 法斯特(Fast)CGI,基于 HTTP 的表达可能不可能正常工作。你可以尝尝在
.htaccess 文件中添加如下内容:

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

无状态的 HTTP 基本注脚

您也得以在运用 HTTP 基本评释时不拔取 session 保存用户的身份到
cookie。这在按照 API
的注明尤其有效。为了形成那么些,你可以定义一个中间件,然后调用 onceBasic
方法。如果 onceBasic 方法没有再次回到响应,那么请求将被愈来愈传递到利用:

<?php

namespace Illuminate\Auth\Middleware;

use Auth;
use Closure;

class AuthenticateOnceWithBasicAuth
{
  /**
   * Handle on incoming request.
   *
   * @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 () {
  // Only authenticated users may enter... 
}]);

自然,你还需要在 kernel.php 大旨中登记该中间件。

密码重置

数据库注意事项

大多数的运用都提供了一种用户重置其忘记密码的章程。laravel
提供了一种便民的艺术来发送密码提示和提供密码重置,这样您就不需要被迫在每个应用都落实一次这种体制。

为了便于起来,请确定你的 App\User 模型实现了
Illuminate\Contracts\Auth\CanResetPassword 契约,laravel 中自带的
App\User 模型中一度实现了那个借口,并且拔取了
Illuminate\Auth\Passwords\CanResetPassword trait。

通过搬迁生成密码重置表

随着,必须要创立一个用来囤积重置密码的 token 的表。laravel
已经提供了这种表的迁徙,并且存放在 database/migrations
目录下,所以,你只需要实施迁移命令:

php artisan migrate

路由

laravel 自带的 Auth\PasswordController
控制器包含了颇具重置密码所需的逻辑。所有提供密码重置的路由都可以由此
make:auth Artisan 命令来扭转:

php artisan make:auth

视图

make:auth 命令被实施时,laravel
会生成所有密码重置所需要的视图。这一个视图将被寄放在
resources/views/auth/passwords 目录中,你可以遵照自己的急需去修改。

重置密码然后

比方您生成了富有重置密码所急需的路由和视图之后,你就可以经过在浏览器访问
/password/reset 路由来开展密码重置。PasswordController
已经包含了发送重置密码的链接邮件及革新密码到数据库的功效。

当密码被重置之后,用户会自动登录并且被重定向到 /home。你可以在
PasswordController 中定义 redirectTo 属性来定制化重定向地址:

protected $redirectTo = '/dashboard';

留意,默认的,密码重置的 token 有效期只有一个刻钟,你可以在
config/auth.php 配置文件中修改 expire 选项。

定制

定制化认证守卫

auth.php 配置文件中,你可以配备多种
“guards”,用于对各类用户表执行认证动作。你可以在 PasswordController
中使用 $guard 属性来摘取守卫:

/**
 * The authentication guard that should be used.
 *
 * @var string
 */
 protected $guard = 'admins';

定制化密码经纪人

auth.php
配置文件中,你可以安排多种密码“brokers”,用于对多种用户表举行密码重置。你可以经过在
PasswordController 中添加 $broker 属性来抉择:

/**
 * The password broker that should be used.
 *
 * @var string
 */
 protected $broker = 'admins';

添加自定义的防守

您可以在服务容器中动用 Auth 假面的 extend 方法来定义自己的注解守卫:

<?php

namespace App\Providers;

use Auth;
use App\Services\Auth\JwtGuard;
use Illuminate\Support\ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
  /**
   * Perform post-registration booting of services.
   *
   * @return void
   */
   public function boot()
   {
     Auth::extend('jwt', function($app, $name, array $config) {
       // Return an instance of Illuminate\Contracts\Auth\Guard...

       return new JwtGuard(Auth::createUserProvider($config['provider']));
     });
   }

   /**
    * Register bindings in the container.
    *
    * @return void
    */
    public function register()
    {
      //
    }
}

您应有能从下面的言传身教中寓目,你应当在 extend 方法中回到一个
Illuminate\Contracts\Auth\Guard
的贯彻。为了定制化守卫你需要贯彻这多少个接口所蕴藏的措施。

假定您的防御被定义,你就能够在 auth.php 配置文件的 guards
选项中展开安排:

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

添加自定义的用户提供者

一经您并没有应用传统的关周全据库来囤积你的用户,那么你需要提供您自己的用户提供者来扩展laravel。你可以通过行使 Auth 假面的 provider
方法来定义自己的用户提供者。你应当在服务提供者中调用该方法:

<?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::provider('riak', function($app, array $config) {
      // Return an instance of Illuminate\Contracts\Auth\UserProvider...
      return new RiakUserProvider($app['riak.connection']);
    });
  }

  /**
   * Rigster bindings in the container.
   *
   * @return void
   */
   public function register()
   {
     //
   }
}

在你使用 provider 方法注册成功提供者之后,你需要在 config/auth.php
配置文件中切换你的用户提供者为新注册的提供者:

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

下一场,你需要在 guards 选项中利用该提供者:

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

用户提供者契约

Illuminate\Contracts\Auth\UserProvider
的实现仅仅只是管理怎么着从持续存储系统中拿走一个
Illuminate\Contracts\Auth\Authenticatable 的实现。如
MySQL,Riak,等等。那些三个接口实现了 laravel
的持续认证机制而不需要考虑用户数据是存放在在哪个地方了或者存放的是何许项目。

让大家来看一下 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
数据库中自增的主键 ID。被匹配的 ID 应该回到一个 Authenticatable
的实现。

retrieveByToken 方法接收用于识别用户身份的绝无仅有标识 $identifier
remember_token 所存储“记住我”的
$token。就如下边的情势一致,该方法应该回到一个 Authenticatable
的实现。

updateRememberToken 方法应用新的 $token 来更新用户的
remember_token 字段。这多少个新的字段可以是用户登录成功还要安装了 记住我
而分红的,也足以是用户登出之后分配的 null。

retrieveByCredentials
方法接收一个数组凭证,它会在用户尝试登录时将凭证传递给 Auth::attemp
方法。该方法会询问底层持续存储设备凭证的匹配意况,一般该方法会动用
where 条件语句来举办查询 $credentials['username']
类似的配合现象。这多少个主意应该回到一个 UserInterface
的实现。无须在这些艺术里做密码验证或者讲明

validateCredentials
方法应该相比较所给定的用户和证据的至极意况。比如,这么些点子恐怕会相比
$user-getAuthPassword()Hash::make 后的
$credentials['password']。这么些艺术应该只做用户和证据间的机能和重临相比意况的布尔值。

可阐明的(Authenticatable)契约

刚刚大家追究了 UserProvider 中的所有办法,现在让我们来看一看
Authenticatable 契约,你应该记得,提供者应该从 retrieveById
retrieveByCredentials 方法中回到该契约接口的贯彻:

<?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
应该回到用户的经哈希后的密码。这一个接口使认证序列可以在其他用户类中运行而不用管你利用的是哪些
ORM 或者另外存储抽象层。默认的,laravel 在 app 目录下富含了 User
类,该类就落实了这一个契约。所以你可以参照那一个类的兑现情势。

事件

laravel 在印证过程中提供了丰盛多彩的风波。你可以在您的
EventServiceProvider 中附加监听那些事件:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
 protected $listen = [
  'Illuminate\Auth\Events\Attempting' => [
    'App\Listeners\LogAuthenticationAttempt',
  ],

  'Illuminate\Auth\Events\Login' => [
    'App\Listeners\LogSuccessfulLogin',
  ],

  'Illuminate\Auth\Events\logout' => [
    'App\Listeners\logSuccessfulLogout',
  ],

  'Illuminate\Auth\Events\Lockout' => [
    'App\Listeners\LogLockout',
  ],
 ];

相关文章