PHPlaravel 基础教程 —— 认证

简介

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 提供了1个火速的方式来变化认证的路由和视图的脚手架,你能够行使
artisan 命令:

php artisan make:auth

在一个新的应用中,这么些命令会用来进行安装注册和登录的视图,也会注入所有的印证相关的路由。HomeController
也会被扭转。那一个控制器提供了 post
登录请求的处理办法。你也得以依照本人的必要删除或涂改那几个控制器。

视图

就如上面所关联的,php artisan make:auth
命令会创设所有认证相关的视图,并且保留在 resources/views/auth 目录下。

make:auth 命令也会成立 resoucres/views/layouts
目录,并在该目录下为运用创造了三个为主的布局。所有的那一个视图都以运用了
Bootstrap CSS 框架,你可以依据自个儿的须要去定制化修改。

举行认证

今昔您早就颇具了认证相关的控制器、路由和视图,你的应用已经拥有了注册和表达的能力。你可以因此浏览器访问你的拔取,认证控制器已经包括了具备的表明用户和存储用户到数据库的措施(通过
traits)。

自定义重定向地址

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

protected $rediredtTo = '/home';

当用户没有认证成功,它会重定向回登录地址。

自定义守卫

你也足以定制化 guard 用来申明用户。你须求在 AuthController 中定义
guard 属性。它的值应该是与您的 auth.php 配置中的某贰个 guards
值相匹配的:

protected $guard = 'admin';

自定义 验证/存储

您恐怕会想要在用户注册时存储一些任何需要的表单字段,进而将新增用户的音信囤积到数据库中,这么些时候你就须要修改
AuthController 类了,那些类老总用户的创办和表单的证实。

AuthController 类中采取 validate
方法来证实验证表单与认证规则的合作程度。你可以依照自己的内需来修改那个方法。

AuthController 类中利用 create
方法用来在数据库中新增一条用户的笔录。这里运用了 Eloquent
OSportageM。你可以根据小编的急需修改那么些形式。

赢得已阐明的用户

您能够由此 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 方法用来回到给重定向器用户在签到前所想要前往的 U帕杰罗L
地址,该方法也接受贰个参数作为所请求地址不可用时的备用地址。

点名额外的评释新闻

比方您必要,你也足以增添部分万分条件做阐明查询,比如,你需求证实被标记为
‘active’ 的用户:

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

注意,在上头的例子中 email
并不是必需的选项,那仅仅只是作为1个示范。你可以行使其它进展用户认证的证据来映射数据库中的字段。

访问指定的防守实例

你可以利用 Auth 假面的 guard
方法来取得你所须要的防守实例。那使你能够在同一个应用中管理五种评释模型或用户表,并已毕独立的证实。

guard 方法中所传递的守护名称应当与安顿文件 auth.php 中 guards
之一相匹配:

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

登出

您可以使用 Auth 假面的 logout
方法来举行用户的脱离,该格局将免去用户认证的对话消息:

Auth::logout();

铭记用户

一旦您想要在您的采纳中提供 记住我 的功效,你只须要在 attempt
方法中传送二个布尔值作为第2个参数,那将保持用户的认证音讯直到用户手动的退出登录。当然,那须求你的用户表中必须包括
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 法斯特CGI,基于 HTTP 的表明只怕不可以符合规律干活。你可以品味在
.htaccess 文件中添加如下内容:

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

无状态的 HTTP 基本声明

您也足以在动用 HTTP 基本注明时不采取 session 保存用户的身份到
cookie。这在依照 API
的评释特别有效。为了成功这个,你能够定义2个中间件,然后调用 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。

因而搬迁生成密码重置表

随后,必须求开创2个用来储存重置密码的 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 方法用来接收七个键来重临2个用户,如 MySQL
数据库中自增的主键 ID。被匹配的 ID 应该回到二个 Authenticatable
的实现。

retrieveByToken 方法接收用于识别用户身份的绝无仅有标识 $identifier
remember_token 所存储“记住我”的
$token。似乎下面的法门同样,该方法应该回到二个 Authenticatable
的实现。

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

retrieveByCredentials
方法接收1个数组凭证,它会在用户尝试登录时将凭证传递给 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
应该回到用户的经哈希后的密码。这些接口使认证种类可以在此外用户类中运维而不用管你选拔的是什么样
OTucsonM 恐怕别的存储抽象层。暗中同意的,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',
  ],
 ];

相关文章