[TOC]
# 安全
该组件帮助开发人员执行常见的安全任务,例如密码散列和跨站请求伪造保护([CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery))。
## Password Hashing
以纯文本格式存储密码是一种糟糕的安全措施。有权访问数据库的任何人都可以立即访问所有用户帐户,从而可以进行未经授权的活动。为了解决这个问题,许多应用程序使用熟悉的单向散列方法'[md5](http://php.net/manual/en/function.md5.php)'和'[sha1](http://php.net/manual/en/function.sha1.php)'。但是,硬件每天都会发展变得越来越快,这些算法越来越容易受到强力攻击。这些攻击也称为[彩虹表](http://en.wikipedia.org/wiki/Rainbow_table)。
为了解决这个问题,我们可以使用哈希算法作为[bcrypt](http://en.wikipedia.org/wiki/Bcrypt)。为什么要加密?由于其'[Eksblowfish](http://en.wikipedia.org/wiki/Bcrypt#Algorithm)'密钥设置算法,我们可以根据需要将密码加密设置为“慢”。慢速算法使得计算哈希背后的真实密码的过程非常困难,如果不是不可能的话。这将使用彩虹表保护您长时间免受可能的攻击。
该组件使您能够以一种简单的方式使用此算法:
```php
<?php
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function registerAction()
{
$user = new Users();
$login = $this->request->getPost('login');
$password = $this->request->getPost('password');
$user->login = $login;
// Store the password hashed
$user->password = $this->security->hash($password);
$user->save();
}
}
```
我们使用默认工作因子保存了密码哈希值。较高的工作因素会使密码不易受到攻击,因为加密速度会很慢。我们可以检查密码是否正确如下:
```php
<?php
use Phalcon\Mvc\Controller;
class SessionController extends Controller
{
public function loginAction()
{
$login = $this->request->getPost('login');
$password = $this->request->getPost('password');
$user = Users::findFirstByLogin($login);
if ($user) {
if ($this->security->checkHash($password, $user->password)) {
// The password is valid
}
} else {
// To protect against timing attacks. Regardless of whether a user
// exists or not, the script will take roughly the same amount as
// it will always be computing a hash.
$this->security->hash(rand());
}
// The validation has failed
}
}
```
使用伪随机字节生成salt,其PHP函数为[openssl_random_pseudo_bytes](http://php.net/manual/en/function.openssl-random-pseudo-bytes.php),因此需要加载openssl扩展。
## 跨站请求伪造(CSRF)保护
这是针对网站和应用程序的另一种常见攻击。用于执行用户注册或添加注释等任务的表单容易受到此攻击。
我们的想法是防止在我们的应用程序之外发送表单值。为了解决这个问题,我们在每个表单中生成一个随机的[随机数](http://en.wikipedia.org/wiki/Cryptographic_nonce)(令牌),在会话中添加令牌,然后在表单通过将会话中存储的令牌与会话中提交的令牌进行比较后将数据发布回应用程序时验证令牌。形成:
```php
<?php echo Tag::form('session/login') ?>
<!-- Login and password inputs ... -->
<input type='hidden' name='<?php echo $this->security->getTokenKey() ?>'
value='<?php echo $this->security->getToken() ?>'/>
</form>
```
然后在控制器的操作中,您可以检查CSRF令牌是否有效:
```php
<?php
use Phalcon\Mvc\Controller;
class SessionController extends Controller
{
public function loginAction()
{
if ($this->request->isPost()) {
if ($this->security->checkToken()) {
// The token is OK
}
}
}
}
```
请记住将会话适配器添加到Dependency Injector,否则令牌检查将不起作用:
```php
<?php
$di->setShared(
'session',
function () {
$session = new \Phalcon\Session\Adapter\Files();
$session->start();
return $session;
}
);
```
建议在表单中添加[验证码](http://www.google.com/recaptcha)以完全避免此攻击的风险。
## 设置组件
此组件作为`security`自动注册在服务容器中,您可以重新注册它以设置其选项:
```php
<?php
use Phalcon\Security;
$di->set(
'security',
function () {
$security = new Security();
// Set the password hashing factor to 12 rounds
$security->setWorkFactor(12);
return $security;
},
true
);
```
## 随机数
`Phalcon\Security\Random`类使得生成许多类型的随机数据变得非常容易。
```php
<?php
use Phalcon\Security\Random;
$random = new Random();
// ...
$bytes = $random->bytes();
// Generate a random hex string of length $len.
$hex = $random->hex($len);
// Generate a random base64 string of length $len.
$base64 = $random->base64($len);
// Generate a random URL-safe base64 string of length $len.
$base64Safe = $random->base64Safe($len);
// Generate a UUID (version 4).
// See https://en.wikipedia.org/wiki/Universally_unique_identifier
$uuid = $random->uuid();
// Generate a random integer between 0 and $n.
$number = $random->number($n);
```
## 外部资源
* [Vökuró](https://vokuro.phalconphp.com)是一个示例应用程序,它使用安全组件来避免CSRF和密码散列,[Github](https://github.com/phalcon/vokuro)
- 常规
- Welcome
- 贡献
- 生成回溯
- 测试重现
- 单元测试
- 入门
- 安装
- Web服务器设置
- WAMP
- XAMPP
- 教程
- 基础教程
- 教程:创建一个简单的REST API
- 教程:Vökuró
- 提升性能
- 教程:INVO
- 开发环境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 开发工具
- Phalcon开发者工具的安装
- Phalcon开发者工具的使用
- 调试应用程序
- 核心
- MVC应用
- 微应用
- 创建命令行(CLI)应用程序
- 依赖注入与服务定位
- MVC架构
- 服务
- 使用缓存提高性能
- 读取配置
- 上下文转义
- 类加载器
- 使用命名空间
- 日志
- 队列
- 数据库
- 数据库抽象层
- Phalcon查询语言(PHQL)
- ODM(对象文档映射器)
- 使用模型
- 模型行为
- ORM缓存
- 模型事件
- 模型元数据
- 模型关系
- 模型事务
- 验证模型
- 数据库迁移
- 分页
- 前端
- Assets管理
- 闪存消息
- 表单
- 图像
- 视图助手(标签)
- 使用视图
- Volt:模板引擎
- 业务逻辑
- 访问控制列表(ACL)
- 注解解析器
- 控制器
- 调度控制器
- 事件管理器
- 过滤与清理
- 路由
- 在session中存储数据
- 生成URL和路径
- 验证
- HTTP
- Cookies管理
- 请求环境
- 返回响应
- 安全
- 加密/解密
- 安全
- 国际化
- 国际化
- 多语言支持