Zend Framework 2参考Zend\Authentication(数据库表认证)
+ 转载自:Zend Framework 2参考Zend\Authentication(数据库表认证)
介绍
Zend\Authentication\Adapter\DbTable提供对存储在数据库表中的凭据进行验证的能力,因为Zend\Authentication\Adapter\DbTable要求Zend\Db\Adapter\Adapter实例进行构造,每个实例绑定到特定的数据库连接。其他配置选项的设置都可以通过构造器实例的方法处理。
可用的配置选项包括
- tableName:这是包含身份验证凭据的数据库表的名称,并针对其中的数据库进行认证查询
- identityColumn:这是用来表示身份数据库表的列的名称。身份列必须包含唯一的值,如用户名或电子邮件地址。
- credentialColumn:这是用来表示证书数据库表的列的名称。一个简单的身份和密码认证方案,证书的值对应的密码。参看
credentialTreatment选项。 - credentialTreatment:在许多情况下,密码和其他敏感数据加密,哈希,编码,模糊,salted或其他函数或算法进行处理。开发者可以通过任意的SQL指定参数化的字串,像’
MD5(?)‘和’PASSWORD(?)‘输入认证数据。由于这些功能具体到底层的RDBMS,请查看数据库手册等功能为你的数据库系统的可用性。
基本用法
正如介绍所说,Zend\Authentication\Adapter\DbTable的构造依赖Zend\Db\Adapter\Adapter实例作为认证适配器实例绑定的数据库连接。首先,应建立数据库连接。
下面的代码创建一个内存中的数据库的适配器,创建一个简单的表schema,并插入一个一行,我们可以稍后执行认证查询。这个例子需要PDO的SQLite扩展可用:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
use Zend\Db\Adapter\Adapter as DbAdapter;// Create a SQLite database connection$dbAdapter = new DbAdapter(array( 'driver' => 'Pdo_Sqlite', 'database' => 'path/to/sqlite.db' ));// Build a simple table creation query$sqlCreate = 'CREATE TABLE [users] (' . '[id] INTEGER NOT NULL PRIMARY KEY, ' . '[username] VARCHAR(50) UNIQUE NOT NULL, ' . '[password] VARCHAR(32) NULL, ' . '[real_name] VARCHAR(150) NULL)';// Create the authentication credentials table$dbAdapter->query($sqlCreate);// Build a query to insert a row for which authentication may succeed$sqlInsert = "INSERT INTO users (username, password, real_name) " . "VALUES ('my_username', 'my_password', 'My Real Name')";// Insert the data$dbAdapter->query($sqlInsert); |
随着数据库连接和表数据已经可用,Zend\Authentication\Adapter\DbTable可以被创建。配置选项的值可以传递给构造函数,setter方法可以作为实例化后参数的变动:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
use Zend\Authentication\Adapter\DbTable as AuthAdapter;// Configure the instance with constructor parameters...$authAdapter = new AuthAdapter($dbAdapter, 'users', 'username', 'password' );// ...or configure the instance with setter methods$authAdapter = new AuthAdapter($dbAdapter);$authAdapter ->setTableName('users') ->setIdentityColumn('username') ->setCredentialColumn('password'); |
除了通过方法getIdentity()返回基于认证结果对象外,通过Zend\Authentication\Adapter\DbTable还可以返回数据表数据确定认证结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// Print the identityecho $result->getIdentity() . "\n\n";// Print the result rowprint_r($authAdapter->getResultRowObject());/* Output:my_usernameArray( [id] => 1 [username] => my_username [password] => my_password [real_name] => My Real Name)*/ |
因为表行里包含证书值,重要的是要防止无意识地访问固定值。
检索结果对象时,我们可以指定哪些列返回,或省略哪些列:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
$columnsToReturn = array( 'id', 'username', 'real_name');print_r($authAdapter->getResultRowObject($columnsToReturn));/* Output:Array( [id] => 1 [username] => my_username [real_name] => My Real Name)*/$columnsToOmit = array('password');print_r($authAdapter->getResultRowObject(null, $columnsToOmit);/* Output:Array( [id] => 1 [username] => my_username [real_name] => My Real Name)*/ |
高级用法:持久化一个DbTable的结果对象
默认情况下,Zend\Authentication\Adapter\DbTable对象的身份验证成功后,返回一个认证对象。另一种用途的情况下,开发人员要存储到持久存储机制的Zend\Authentication标识对象包括其他有用信息,解决方法是getResultRowObject()返回一个stdClass对象,下面的代码片段说明了它的用法:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// authenticate with Zend\Authentication\Adapter\DbTable$result = $this->_auth->authenticate($adapter);if ($result->isValid()) { // store the identity as an object where only the username and // real_name have been returned $storage = $this->_auth->getStorage(); $storage->write($adapter->getResultRowObject(array( 'username', 'real_name', ))); // store the identity as an object where the password column has // been omitted $storage->write($adapter->getResultRowObject( null, 'password' )); /* ... */} else { /* ... */} |
高级用法范例
虽然Zend\Authentication组件的主要目的(所以Zend\Authentication\Adapter\DbTable)是认证而不是授权,但是基于它们用在哪个域名下,还是有一些实例和问题。根据如何解释你的问题,有时候通过在认证适配器里检查授权问题也许能解决问题。
有了这样的声明的方式,Zend\Authentication\Adapter\DbTable有一些内置的机制,可以利用额外的检查认证时间来解决一些普通的用户问题。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
use Zend\Authentication\Adapter\DbTable as AuthAdapter;// The status field value of an account is not equal to "compromised"$adapter = new AuthAdapter($db, 'users', 'username', 'password', 'MD5(?) AND status != "compromised"' );// The active field value of an account is equal to "TRUE"$adapter = new AuthAdapter($db, 'users', 'username', 'password', 'MD5(?) AND active = "TRUE"' ); |
另外一个场景是免疫机制的实施。免疫是一个术语,指的是一种技术的高度可以提高应用程序的安全。它是基于连接随机字符串到每个密码的想法,使得它不可能完成一个成功的蛮力攻击对数据库使用预先计算好的哈希值从字典。
因此,我们需要修改表来存储我们的免疫字符串:
|
1
2
3
|
$sqlAlter = "ALTER TABLE [users] " . "ADD COLUMN [password_salt] " . "AFTER [password]"; |
这里有一个简单的方法来为每个用户在注册生成免疫字符串:
|
1
2
3
4
|
$dynamicSalt = '';for ($i = 0; $i < 50; $i++) { $dynamicSalt .= chr(rand(33, 126));} |
现在让我们来构建适配器:
|
1
2
3
4
5
6
|
$adapter = new AuthAdapter($db, 'users', 'username', 'password', "MD5(CONCAT('staticSalt', ?, password_salt))" ); |
注意:通过使用一个静态的免疫硬编码到应用程序中,您可以更好地改善安全。在您的数据库被攻破的情况下(例如SQL注入攻击),但你的数据仍然是是完好的而无法攻击您的Web服务器。
另一种替代方法是在Zend\Authentication\Adapter\DbTable构造完成后使用getDbSelect()方法,
此方法将返回Zend\Db\Sql\Select实例将用于完成常规的authenticate(),重点要注意的是,这种方法将始终返回相同的对象,无论authenticate()是否被调用。因为这些值在authenticate()被放入的选择对象时,这个对象将不会有任何的身份或凭据信息。
下面一个例子可能要使用getDbSelect()方法会检查用户的状态(如果该用户的帐户被启用的情况下)。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// Continuing with the example from above$adapter = new AuthAdapter($db, 'users', 'username', 'password', 'MD5(?)' );// get select object (by reference)$select = $adapter->getDbSelect();$select->where('active = "TRUE"');// authenticate, this ensures that users.active = TRUE$adapter->authenticate();
|
Zend Framework 2参考Zend\Authentication(数据库表认证)的更多相关文章
- Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍)
原文:Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍) Zend\Authentication组件提供了认证接口和具体的通用的认 ...
- Zend Framework 2参考Zend\Authentication(HTTP认证适配器)
Zend Framework 2参考Zend\Authentication(HTTP认证适配器) 介绍 Zend\Authentication\Adapter\Http提供了RFC-2617, Bas ...
- Zend Framework 2参考Zend\Authentication(摘要式身份验证)
Zend Framework 2参考Zend\Authentication(摘要式身份验证) 介绍 摘要式身份验证是HTTP身份验证的方法,提高了基本身份验证时提供的方式进行身份验证,而无需在网络上以 ...
- 关于Zend Framework 2中 Zend\Session的使用
一直迷惑于zend\Session的使用,这个是Zend\Session的官方教程的中文版,http://zend-framework-2.yangfan.co/blog/556. 其中最重要的是关于 ...
- Zend Framework 1 - Quick Start
创建 Zend 项目 要创建 Zend 项目,首先要下载并解压 Zend Framework. 安装 Zend Framework 下载最新的 Zend Framework 1.12.20 源码包,( ...
- Zend Framework 留言本实战(转)
一.环境搭建和ZF安装 *[注]本节内容大部分来至Zend Framework官方手册 1.1 Zend Framework下载 Zend Framework 使 ...
- 主流PHP框架间的比较(Zend Framework,CakePHP,CodeIgniter,Symfony,ThinkPHP,FleaPHP)
Zend Framework 优点: Zend Framework大量应用了PHP5中面向对象的新特征:接口.异常.抽象类.SPL等等.这些东西的应用让Zend Framework具有高度的模块化和灵 ...
- Zend Framework XML外部实体和安全绕过漏洞
漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...
- Zend Framework学习日记(2)--HelloWorld篇(转)
Zend Framework学习日记(2)--HelloWorld篇 这一篇主要演示如何用zf命令行工具建立一个基于Zend Framework框架的工程,也是我初学Zend Framework的小练 ...
随机推荐
- c语言的笔记
下面把我这半年来记的一些C语言的笔记贴出来. 1 C语言中函数参数传递是按照“值传递”进行的,即单向传递. 2 函数原型:函数类型 函数名(参数类型,参数类型……),可以不必加参数名,因为操作系统 ...
- makefile中PHONY的重要性
伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行所在规则定义的命令,有时也可以将一个伪目标称为标签.伪目标通过 PHONY来指明. PHONY定义伪目标的命令 ...
- C技巧:结构体参数转成不定参数
下面这段程序是一个C语言的小技巧,其展示了如何把一个参数为结构体的函数转成一个可变参数的函数,其中用到了宏和内建宏"__VA_ARGS__",下面这段程序可以在GCC下正常编译通过 ...
- WordPress 前端投稿/编辑插件 DJD Site Post(支持游客和已注册用户)
转自:http://www.wpdaxue.com/front-end-publishing.html 说到前端用户投稿,倡萌之前推荐过3个不错的插件: WordPress匿名投稿插件:DX-Cont ...
- BZOJ 1592: [Usaco2008 Feb]Making the Grade 路面修整
Description FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中. 整条路被分成了 ...
- Mozilla公布WebVR API标准草案
随着信息技术的迅速发展,虚拟现实(Virtual Reality,VR)技术在近些年不断完善,其应用范围也变得十分广泛.为了搭建逼真的虚拟场景,VR技术一般都需要用到大量精美的图像和复杂的动作.因此, ...
- Stanford Parser学习入门(2)-命令行运行
在Stanford parser目录中已经定义了一部分命令行工具以及图形界面,本文将介绍如何在windows使用这些工具进行语法分析,Linux下也有shell可以使用. 关于如何搭建环境请参考上一篇 ...
- 一篇文章让你读懂 OpenStack 的起源、架构和应用
OpenStack 是一个面向 IaaS 层的开源项目,用于实现公有云和私有云的部署及管理.拥有众多大公司的行业背书和数以千计的社区成员, OpenStack 被看作是云计算的未来.目前 OS 基金会 ...
- VLAN间单臂路由访问
实验书上的拓朴图: 注意TRUNK端口和路由器子端口设置,可以承载不同的VLAN标签. 交换机(用2691加交换模块实现的): Building configuration... Current co ...
- [cocos2dx]计算scrollview元素的index
scrollview的原生代码没有提供元素对齐功能 通过下面介绍的index计算方法以及scrollview自带的设置位置方法 void setContentOffsetInDuration(CCPo ...