[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管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持