W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
注意:本節(jié)內(nèi)容正在開(kāi)發(fā)中。
好的安全策略對(duì)任何應(yīng)用的健康和成功極其重要。不幸的是,許多開(kāi)發(fā)者在遇到安全問(wèn)題時(shí),因?yàn)檎J(rèn)識(shí)不夠或者實(shí)現(xiàn)起來(lái)比較麻煩,都不是很注意細(xì)節(jié)。為了讓你的 Yii 應(yīng)用程序盡可能的安全, Yii 囊括了一些卓越并簡(jiǎn)單易用的安全特性。
大部分開(kāi)發(fā)者知道密碼不能以明文形式存儲(chǔ),但是許多開(kāi)發(fā)者仍認(rèn)為使用?md5
?或者?sha1
?來(lái)哈希化密碼是安全的。一度,使用上述的哈希算法是足夠安全的,但是,現(xiàn)代硬件的發(fā)展使得短時(shí)間內(nèi)暴力破解上述算法生成的哈希串成為可能。
為了即使在最糟糕的情況下(你的應(yīng)用程序被破解了)也能給用戶密碼提供增強(qiáng)的安全性,你需要使用一個(gè)能夠?qū)贡┝ζ平夤舻墓K惴?。目前最好的選擇是?bcrypt
。在 PHP 中,你可以通過(guò)?crypt 函數(shù)?生成?bcrypt
?哈希。Yii 提供了兩個(gè)幫助函數(shù)以讓使用crypt
?來(lái)進(jìn)行安全的哈希密碼生成和驗(yàn)證更加容易。
當(dāng)一個(gè)用戶為第一次使用,提供了一個(gè)密碼時(shí)(比如:注冊(cè)時(shí)),密碼就需要被哈?;?。
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
哈希串可以被關(guān)聯(lián)到對(duì)應(yīng)的模型屬性,這樣,它可以被存儲(chǔ)到數(shù)據(jù)庫(kù)中以備將來(lái)使用。
當(dāng)一個(gè)用戶嘗試登錄時(shí),表單提交的密碼需要使用之前的存儲(chǔ)的哈希串來(lái)驗(yàn)證:
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
// all good, logging user in
} else {
// wrong password
}
偽隨機(jī)數(shù)據(jù)在許多場(chǎng)景下都非常有用。比如當(dāng)通過(guò)郵件重置密碼時(shí),你需要生成一個(gè)令牌,將其保存到數(shù)據(jù)庫(kù)中,并通過(guò)郵件發(fā)送到終端用戶那里以讓其證明其對(duì)某個(gè)賬號(hào)的所有權(quán)。這個(gè)令牌的唯一性和難猜解性非常重要,否則,就存在攻擊者猜解令牌,并重置用戶的密碼的可能性。
Yii security helper makes generating pseudorandom data simple: Yii 安全助手使得生成偽隨機(jī)數(shù)據(jù)非常簡(jiǎn)單:
$key = Yii::$app->getSecurity()->generateRandomString();
注意,你需要安裝有?openssl
?擴(kuò)展,以生成密碼的安全隨機(jī)數(shù)據(jù)。
Yii 提供了方便的幫助函數(shù)來(lái)讓你用一個(gè)安全秘鑰來(lái)加密解密數(shù)據(jù)。數(shù)據(jù)通過(guò)加密函數(shù)進(jìn)行傳輸,這樣只有擁有安全秘鑰的人才能解密。比如,我們需要存儲(chǔ)一些信息到我們的數(shù)據(jù)庫(kù)中,但是,我們需要保證只有擁有安全秘鑰的人才能看到它(即使應(yīng)用的數(shù)據(jù)庫(kù)泄露)
// $data and $secretKey are obtained from the form
$encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey);
// store $encryptedData to database
隨后,當(dāng)用戶需要讀取數(shù)據(jù)時(shí):
// $secretKey is obtained from user input, $encryptedData is from the database
$data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey);
有時(shí),你需要驗(yàn)證你的數(shù)據(jù)沒(méi)有第三方篡改或者使用某種方式破壞了。Yii 通過(guò)兩個(gè)幫助函數(shù),提供了一個(gè)簡(jiǎn)單的方式來(lái)進(jìn)行數(shù)據(jù)的完整性校驗(yàn)。
首先,將由安全秘鑰和數(shù)據(jù)生成的哈希串前綴到數(shù)據(jù)上。
// $secretKey our application or user secret, $genuineData obtained from a reliable source
$data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey);
驗(yàn)證數(shù)據(jù)完整性是否被破壞了。
// $secretKey our application or user secret, $data obtained from an unreliable source
$data = Yii::$app->getSecurity()->validateData($data, $secretKey);
todo: XSS 防范, CSRF 防范, Cookie 保護(hù)相關(guān)的內(nèi)容,參考 1.1 文檔
你同樣可以給控制器或者 action 設(shè)置它的?enableCsrfValidation
?屬性來(lái)單獨(dú)禁用 CSRF 驗(yàn)證。
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $enableCsrfValidation = false;
public function actionIndex()
{
// CSRF validation will not be applied to this and other actions
}
}
為了給某個(gè)定制的 action 關(guān)閉 CSRF 驗(yàn)證,你可以:
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function beforeAction($action)
{
// ...set `$this->enableCsrfValidation` here based on some conditions...
// call parent method that will check CSRF if such property is true.
return parent::beforeAction($action);
}
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: