文档章节

From Apprentice To Artisan 翻译 15

zgldh
 zgldh
发布于 2015/02/21 16:25
字数 2294
阅读 3229
收藏 1

上一篇

Authentication 身份认证

Authentication may be extended the same way as the cache and session facilities. Again, we will use the extend method we have become familiar with:

身份认证模块的扩展方式和缓存与会话的扩展方式一样:使用我们熟悉的extend方法就可以进行扩展:

<!-- lang: php -->
Auth::extend('riak', function($app)
{
    // Return implementation of Illuminate\Auth\UserProviderInterface
});

The UserProviderInterface implementations are only responsible for fetching a UserInterface implementation out of persistent storage system, such as MySQL, Riak, etc. These two interfaces allow the Laravel authentication mechanisms to continue functioning regardless of how the user data is stored or what type of class is used to represent it.

接口UserProviderInterface负责从各种持久化存储系统——如MySQL,Riak等——中获取数据,然后得到接口UserInterface的实现对象。有了这两个接口,Laravel的身份认证机制就可以不用管用户数据是如何储存的、究竟哪个类来代表用户对象这种事儿,从而继续专注于身份认证本身的实现。

Let's take a look at the UserProviderInterface:

咱们来看一看UserProviderInterface接口的代码:

<!-- lang:php -->
interface UserProviderInterface {
    public function retrieveById($identifier);
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(UserInterface $user, array $credentials);
}

The retrieveById function typically receives a numeric key representing the user, such as an auto-incrementing ID from a MySQL database. The UserInterface implementation matching the ID should be retrieved and returned by the method.

方法retrieveById通常接受一个数字参数用来表示一个用户,比如MySQL数据库的自增ID。该方法要找到匹配该ID的UserInterface的实现对象,并且将该对象返回。

The retrieveByCredentials method receives the array of credentials passed to the Auth::attempt method when attempting to sign into an application. The method should then "query" the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a "where" condition on $credentials['username']. This method should not attempt to do any password validation or authentication.

retrieveByCredentials方法接受一个参数作为登录帐号。该参数是在尝试登录系统时从Auth::attempt方法传来的。那么该方法应该“查询”底层的持久化存储系统,来找到那些匹配到该帐号的用户。通常该方法会执行一个带有“where”条件的查询来匹配参数里的$credentials['username']该方法不应该做任何密码验证。

The validateCredentials method should compare the given $user with the $credentials to authenticate the user. For example, this method might compare the $user->getAuthPassword(); string to a Hash::make of $credentials['password'].

validateCredentials方法会通过比较$user参数和$credentials参数来检测用户是否通过认证。比如,该方法会调用$user->getAuthPassword();方法,将得到的字符串与$credentials['password']经过Hash::make处理后的结果进行比对。

Now that we have explored each of the methods on the UserProviderInterface, let's take a look at the UserInterface. Remember, the provider should return implementations of this interface from the retrieveById and retrieveByCredentials methods:

现在我们探索了UserProviderInterface接口的每一个方法,接下来咱们看一看UserInterface接口。别忘了UserInterface的实例应当是retrieveByIdretrieveByCredentials方法的返回值:

<!-- lang:php -->
interface UserInterface {
    public function getAuthIdentifier();
    public function getAuthPassword();
}

This interface is simple. The getAuthIdentifier method should return the "primary key" of the user. In a MySQL back-end, again, this would be the auto-incrementing primary key. The getAuthPassword should return the user's hashed password. This interface allows the authentication system to work with any User class, regardless of what ORM or storage abstraction layer you are using. By default, Laravel includes a User class in the app/models directory which implements this interface, so you may consult this class for an implementation example.

这个接口很简单。 getAuthIdentifier方法应当返回用户的“主键”。就像刚才提到的,在MySQL中可能就是自增主键了。getAuthPassword方法应当返回经过散列处理的用户密码。有了这个接口,身份认证系统就可以不用关心用户类到底使用了什么ORM或者什么存储方式。Laravel已经在app/models目录下,包含了一个默认的User类且实现了该接口。所以你可以参考这个类当例子。

Finally, once we have implemented the UserProviderInterface, we can ready to register our extension with the Auth facade:

当我们最后实现了UserProviderInterface接口后,我们可以将该扩展注册进Auth里面:

<!-- lang:php -->
Auth::extend('riak', function($app)
{
    return new RiakUserProvider($app['riak.connection']);
});

After you have registered the driver with the extend method, you switch to the new driver in your app/config/auth.php configuration file.

使用extend方法注册好驱动以后,你就可以在app/config/auth.php配置文件里面切换到新的驱动了。

IoC Based Extension 使用容器进行扩展

Almost every service provider included with the Laravel framework binds objects into the IoC container. You can find a list of your application's service providers in the app/config/app.php configuration file. As you have time, you should skim through each of these provider's source code. By doing so, you will gain a much better understanding of what each providers adds to the framework, as well as that keys are used to bind various services into the IoC container.

Laravel框架内几乎所有的服务提供者都会绑定一些对象到IoC容器里。你可以在app/config/app.php文件里找到服务提供者列表。如果你有时间的话,你应该大致过一遍每个服务提供者的源码。这么做你便可以对每个服务提供者有更深的理解,明白他们都往框架里加了什么东西,对应的什么键。那些键就用来联系着各种各样的服务。

For example, the PaginationServiceProvider binds a paginator key into the IoC container, which resolves into Illuminate\Pagination\Environment instance. You can easily extend and override this class within your own application by overriding this IoC binding. For example, you could create a class that extend the base Environment:

举个例子,PaginationServiceProvider向容器内绑定了一个paginator键,对应着一个Illuminate\Pagination\Environment的实例。你可以很容易的通过覆盖容器绑定来扩展重写该类。比如,你可以创建一个扩展自Environment类的子类:

<!-- lang:php -->
namespace Snappy\Extensions\Pagination;
class Environment extends \Illuminate\Pagination\Environment {
    //
}

Once you have created your class extension, you may create a new SnappyPaginationProvider service provider class which overrides the paginator in its boot method:

子类写好以后,你可以再创建个新的SnappyPaginationProvider服务提供者来扩展其boot方法,在里面覆盖 paginator:

<!-- lang:php -->
class SnappyPaginationProvider extends PaginationServiceProvider {
    public function boot()
    {
        App::bind('paginator', function()
        {
            return new Snappy\Extensions\Pagination\Environment;
        }

        parent::boot();
    }
}

Note that this class extends the PaginationServiceProvider, not the default ServiceProvider base class. Once you have extended the service provider, swap out the PaginationServiceProvider in your app/config/app.php configuration file with the name of your extended provider.

注意这里我们继承了PaginationServiceProvider,而非默认的基类ServiceProvider。扩展的服务提供者编写完毕后,就可以在app/config/app.php文件里将PaginationServiceProvider替换为你刚扩展的那个类了。

This is the general method of extending any core class that is bound in the container. Essentially every core class is bound in the container in this fashion, and can be overridden. Again, reading through the included framework service providers will familiarize you with where various classes are bound into the container, and what keys they are bound by. This is a great way to learn more about how Laravel is put together.

这就是扩展绑定进容器的核心类的一般方法。基本上每一个核心类都以这种方式绑定进了容器,都可以被重写。还是那一句话,读一遍框架内的服务提供者源码吧。这有助于你熟悉各种类是怎么绑定进容器的,都绑定的是哪些键。这是学习Laravel框架到底如何运转的好方法。

Request Extension 请求的扩展

Because it is such a foundational piece of the framework and is instantiated very early in the request cycle, extending the Request class works a little differently than the previous examples.

由于这玩意儿是框架里面非常基础的部分,并且在请求流程中很早就被实例化,所以要扩展Request类的方法与之前相比是有些许不同的。

First, extend the class like normal:

首先还是要写个子类:

<!-- lang:php -->
namespace QuickBill\Extensions;
class Request extends \Illuminate\Http\Request {
    // Custom, helpful methods here...
}

Once you have extended the class, open the bootstrap/start.php file. This file is one of the very first files to be included on each request to your application. Note that the first action performed is the creation of the Laravel $app instance:

子类写好后,打开bootstrap/start.php文件。该文件是应用的请求流程中最早被载入的几个文件之一。要注意被执行的第一个动作是创建Laravel的$app实例:

<!-- lang:php -->
$app = new \Illuminate\Foundation\Application;

When a new application instance is created, it will create a new Illuminate\Http\Request instance and bind it to the IoC container using the request key. So, we need a way to specify a custom class that should be used as the "default" request type, right? And, thankfully, the requestClass method on the application instance does just this! So, we can add this line at the very top of our bootstrap/start.php file:

当新的应用实例创建后,它将会创建一个Illuminate\Http\Request的实例并且将其绑定到IoC容器里,键名为request。所以我们需要找个方法来将一个自定义的类指定为“默认的”请求类,对不对?而且幸运的是,应用实例有一个名为requestClass的方法就是用来干这事儿的!所以我们只需要在bootstrap/start.php文件最上面加一行:

<!-- lang:php -->
use Illuminate\Foundation\Application;
Application::requestClass('QuickBill\Extensions\Request');

Once you have specified the custom request class, Laravel will use this class anytime it creates a Request instance, conveniently allowing you to always have an instance of your custom request class available, even in unit test!

一旦你指定了自定义的请求类,Laravel 将在任何时候都可以使用这个Request类的实例。并使你很方便的能随时访问到它,甚至单元测试也不例外!

下一篇

© 著作权归作者所有

共有 人打赏支持
zgldh
粉丝 95
博文 35
码字总数 46344
作品 2
高级程序员
私信 提问
From Apprentice To Artisan 翻译 20

上一篇 Dependency Inversion Principle 依赖反转原则 Introduction 介绍 We have reached our final destination in our overview of the five SOLID design principles! The final princip......

zgldh
2015/03/19
0
4
From Apprentice To Artisan 翻译 17

上一篇 Open Closed Principle 开放封闭原则 Introduction 介绍 Over the life time of an application, more time is spent adding to the existing codebase rather than constantly addi......

zgldh
2015/03/18
0
0
From Apprentice To Artisan 翻译 08

上一篇 As Organizer 作为管理工具 One of the keys to building a well architected Laravel application is learning to use service providers as an organizational tool. When you are ......

zgldh
2014/12/09
0
0
From Apprentice To Artisan 翻译 02

上一篇 Taking It Further 更进一步 Let's consider another example to solidify our understanding. Perhaps we want to notify customers of charges to their account. We'll define tw......

zgldh
2014/08/22
0
1
From Apprentice To Artisan 翻译 16

上一篇 Single Responsibility Principle 单一职责原则 Introduction 介绍 The "SOLID" design principles, articulated by Robert "Uncle Bob" Martin, are five principles that provide ......

zgldh
2015/03/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Apache日志不记录访问静态文件,访问日志切割,静态元素过期时间设置

Apache配置不记录访问静态文件的日志 网站大多元素为静态文件,如图片、css、js等,这些元素可以不用记录 vhost原始配置 <VirtualHost *:80> ServerAdmin test@163.com DocumentRoo...

野雪球
38分钟前
0
0
聊聊storm的ICommitterTridentSpout

序 本文主要研究一下storm的ICommitterTridentSpout ICommitterTridentSpout storm-core-1.2.2-sources.jar!/org/apache/storm/trident/spout/ICommitterTridentSpout.java public interface......

go4it
42分钟前
1
0
Ubuntu常用操作

查看端口号 netstat -anp |grep 端口号 查看已使用端口情况 netstat -nultp(此处不用加端口号) netstat -anp |grep 82查看82端口的使用情况 查找被占用的端口: netstat -tln netstat -tl...

hc321
昨天
1
0
网站cdn的静态资源突然访问变的缓慢,问题排查流程

1.首先我查看了一下是否自己的网络问题,通过对比其他资源的访问速度和下载速度,确认不是 2.通过ping 和 tracert 判断cdn域名能否正常访问,(最后回想感觉这一步可以省略,因为每次最终能访...

小海bug
昨天
3
0
Mybatis 学习笔记四 MyBatis-Plus插件

Mybatis 学习笔记四 MyBatis-Plus插件 maven依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <ve......

晨猫
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部