Yii2編程:安全性

PHPz
發布: 2023-09-05 06:00:01
原創
615 人瀏覽過

Yii2編程:安全性

如果您問「Yii 是什麼?」查看Yii 框架簡介,其中回顧了Yii 的優點並包含Yii 2.0 的概述。

在這個使用 Yii2 程式設計系列中,我將引導讀者使用 Yii2 PHP 框架。如果您計劃與公眾共享您的應用程序,則需要它是安全的,並且最好從一開始就計劃好。幸運的是,從像 Yii 這樣的框架開始,這比其他框架要容易得多。如 Yii 的功能所述:

Yii 配備了許多安全措施來幫助防止您的 Web 應用程式遭受 SQL 注入、跨站點腳本 (XSS)、跨站點請求偽造 (CSRF) 和 cookie 篡改等攻擊。

在本教程中,我將引導您了解 Yii 應用程式框架內的基本安全概念。而且,如果您有興趣,隨著我們的啟動系列中的會議計劃器應用程式接近 Alpha 版本,未來的幾集將致力於確保該應用程式的安全。

在我們開始之前,請記住,我確實嘗試參與下面的討論。如果您有問題或主題建議,請在下面發表評論或透過 Twitter @reifman 與我聯繫。

#注意:如果您注意到「Programming Yii」系列劇集之間存在著間隙,那是因為我去年必須進行腦部手術。感謝您的耐心和支持——很高興再次定期撰寫文章,我期待繼續報導 Yii2。

Yii 安全基礎知識

如果您是 Web 應用程式安全的新手,那麼關於 Yii 的產品有很多內容需要了解。我將盡力根據最好的 Yii 2.0 文件提供概述。 Yii 團隊將安全性分為七個關鍵領域:

  1. 身份驗證
  2. 授權
  3. 使用密碼
  4. 密碼學
  5. 查看安全性
  6. 身份驗證客戶端
  7. 最佳實踐

讓我們開始一一深入研究這些內容。

#1。身份驗證

Ilko Kacharov 的 Yii 框架安全性簡報提供了一些有用的投影片,總結了身分驗證的目標(以及以下子主題,授權)。本質上,以下是這些主題需要回答的問題:

  • 用戶是誰?
  • 使用者就是他們所說的那樣嗎?
  • 使用者是否有權存取資源?
  • 使用者是否有權執行某項操作?
  • 使用者是否有權對資源執行操作?

使用者模型和身分介面

Yii 的 yii/web/User 類別與 yii\web\IdentityInterface 集成,以管理應用程式中使用者的驗證狀態。

去年 11 月,我寫了一篇關於 Yii 高階應用程式範本的教學。高級模板的優點之一是它提供了使用者模型與 ActiveRecord 和資料庫的預先建置整合。因此,您的應用程式立即提供資料庫驅動的身份驗證。

#使用者模型可讓您以程式設計方式登入和登出使用者:

  • login() 設定指定的身份並記住會話和 cookie 中的身份驗證狀態。
  • logout() 將使用者標記為訪客,並清除會話和 Cookie 中的相關資訊。
  • setIdentity():在不接觸會話或 cookie 的情況下變更使用者身份,最適合 API 功能。

$isGuest 屬性決定目前使用者是否已登入。當使用者登出時,它為 null,但否則傳回 IdentityInterface 的實例。

#本質上,您需要一個擴展 ActiveRecord 並實作支援 IdentityInterface 的方法的 User 類,如下所示:

<?php

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    public static function tableName()
    {
        return 'user';
    }

    /**
     * Finds an identity by the given ID.
     *
     * @param string|integer $id the ID to be looked for
     * @return IdentityInterface|null the identity object that matches the given ID.
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    /**
     * Finds an identity by the given token.
     *
     * @param string $token the token to be looked for
     * @return IdentityInterface|null the identity object that matches the given token.
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    /**
     * @return int|string current user ID
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string current user auth key
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @param string $authKey
     * @return boolean if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}
登入後複製

此外,在創建使用者之前,應用程式會產生一個隨機字串作為授權金鑰。這可以用在「忘記密碼」電子郵件或其他基於電子郵件的登入連結中:

class User extends ActiveRecord implements IdentityInterface
{
    ......
    
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}
登入後複製

授權

Yii 提供了兩種內建的授權方法。更簡單的存取控制清單 (ACL) 決定允許哪些使用者或進程對資源執行操作,而更密集的基於角色的存取控制 (RBAC) 可協助您透過定義角色來管理存取權限。在RBAC中,只有具有特定角色的使用者或系統任務才能執行特定操作。

存取控制清單

ACL 有時也稱為存取控制過濾器 (ACF)。 Yii 在 yii\filters\AccessControl 中提供 ACL 支援。它非常適合只需要簡單存取控制的應用程式。這是我迄今為止在 Meeting Planner 中使用的內容。

以下是常見 SiteController 的範例,該範例配置存取行為以過濾對可用操作(通常是頁面)的存取。在本例中,ACL 作用於註冊、登入和登出。 '?' 表示任何使用者都可以存取登入和註冊頁面,而 '@' 表示僅允許登入或經過驗證的使用者存取。在下面的範例中,只有登入的使用者才能登出:

use yii\web\Controller;
use yii\filters\AccessControl;

class SiteController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['login', 'logout', 'signup'],
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['login', 'signup'],
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['logout'],
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }
    // ...
}
登入後複製

随着控制器的增长,每个新操作都需要在访问控制规则中定义。而且,随着应用程序的增长,每个控制器及其所有操作都需要集成 ACL 过滤以确保安全。

基于角色的访问控制

基于角色的访问控制(RBAC)提供了更强大的身份验证系统,但也需要更多的前期设计和实现。

使用 RBAC,您可以通过可以继承(或不可继承)的角色来定义身份验证,并将角色应用于用户。您还可以定义角色规则。 RBAC 实现可能会变得相当复杂。

在下图中,管理员可以执行任何任务,作者可以创建帖子并更新自己的帖子。 Jane 是管理员,因此她可以执行管理员的任务,而 John 只是作者:

Yii2編程:安全性

Yii 实现了所谓的“通用分层 RBAC,遵循 NIST RBAC 模型”。 RBAC 功能由其 authManager 应用程序组件提供。

我不会在这里深入探讨 RBAC,但我希望在以后的教程中能够深入探讨。再说一次,这取决于编辑女神——与她们交谈绝非易事:

Yii2編程:安全性

基本上,要彻底实施 RBAC,您必须:

  • 定义角色和权限
  • 建立您的角色和权限之间的关系
  • 定义任何现有的规则
  • 将规则与您的角色和权限相关联
  • 最后,为用户分配角色

您可以在下面看到启用 RBAC 系统所需的代码:

<?php
namespace app\commands;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        // add "createPost" permission
        $createPost = $auth->createPermission('createPost');
        $createPost->description = 'Create a post';
        $auth->add($createPost);

        // add "updatePost" permission
        $updatePost = $auth->createPermission('updatePost');
        $updatePost->description = 'Update post';
        $auth->add($updatePost);

        // add "author" role and give this role the "createPost" permission
        $author = $auth->createRole('author');
        $auth->add($author);
        $auth->addChild($author, $createPost);

        // add "admin" role and give this role the "updatePost" permission
        // as well as the permissions of the "author" role
        $admin = $auth->createRole('admin');
        $auth->add($admin);
        $auth->addChild($admin, $updatePost);
        $auth->addChild($admin, $author);

        // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()
        // usually implemented in your User model.
        $auth->assign($author, 2);
        $auth->assign($admin, 1);
    }
}
登入後複製

要实现 RBAC,您必须准备好预先编写大量代码,或者随着应用程序的增长而编写大量代码。而且,如果您这样做,Yii 将根据您定义的身份验证框架来管理身份验证。换句话说,预先设计和编码可以提供可靠、详细的身份验证。

使用密码

正如马克·扎克伯格 (Mark Zuckerberg) 在 6 月份了解到的那样,一些网站以纯文本形式存储用户密码,但您的网站不应该这样做;公平地说,在密码管理器时代之前,我的 Facebook 帐户曾经因 PHPList 所做的事情而被黑客入侵过。不管怎样,Yii 使得加密和安全验证密码变得很容易。

Yii 的 crypt 函数使用 bcrypt 为您的密码生成哈希值。当人们注册时,会创建一个哈希值:

$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
登入後複製

然后,当用户尝试登录时,它会被散列并与数据库中的散列进行比较:

if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
    // all good, logging user in
} else {
    // wrong password
}
登入後複製

但是您也可以使用 Yii 通过加密来保护数据。

密码学

Yii 框架提供了许多内置功能来支持数据保护:

  • 密码和密钥生成函数,例如generateRandomKey、generateRandomString 和generateSalt。
  • 密码验证:generatePasswordHash() 和 validatePassword()。
  • 加密/解密:encryptByKey()、decryptByKey()、encryptByPassword() 和 decryptByPassword()。
  • 使用标准算法派生密钥:pbkdf2() 和 hkdf()。
  • 防止数据篡改:hashData() 和 validateData()。

查看安全性

来自用户的任何数据都可能受到 SQL 注入或跨浏览器脚本等攻击的感染。重要的是,您在视图中输出给用户的任何数据都应该被清理。 Yii 为此提供了几种方法。

首先,有 Html::encode,它基本上破坏了任何 SQL 或脚本:

<?php
use yii\helpers\Html;
?>

<div class="username">
    <?= Html::encode($user->name) ?>
</div>
登入後複製

并且与 HtmlPurifier 库集成以实现更大的文本块:

<?php
use yii\helpers\HtmlPurifier;
?>

<div class="post">
    <?= HtmlPurifier::process($post->text) ?>
</div>
登入後複製

通过身份验证客户端登录

Yii 还提供了第三方身份验证的功能,这对于支持通过 Google、Facebook、Twitter 等进行社交登录尤其有用。

我为 Envato Tuts+ 编写了几篇关于在 Yii 框架内使用 AuthClient 进行社交登录的教程:

  • 构建您的初创公司:使用 AuthClient 简化入口(待发布
  • 如何使用 Yii2 进行编程:Google 身份验证
  • 如何使用 Yii2 进行编程:AuthClient 与 Twitter、Google 和其他网络集成

我发现社交登录对于会议策划者来说效果非常好。新用户无需密码即可开始安排会议。

最佳实践

Yii 还推荐了一些 Web 应用程序安全方面的最佳实践。它的文档为任何人提供了有关这些主题的良好入门知识。

  1. 过滤输入和输出
  2. 避免 SQL 注入
  3. 避免跨站脚本 (XSS)
  4. 避免跨站请求伪造 (CSRF)
  5. 避免文件泄露
  6. 在生产中避免调试信息和工具
  7. 使用通过 TLS 的安全连接

上面的前三个主题可以通过上面视图安全中讨论的编码得到很好的管理。

Yii 還為常見活動提供內建的 CSRF 保護,並且可以在需要時將其關閉。在 Meeting Planner 中,我必須關閉 CSRF 才能接受從 Mailgun 的 API 服務發布的訊息。

對於文件暴露,該框架透過將所有輸入請求集中到 web/index.php 請求文件中來幫助最大限度地減少這種情況。這極大地限制了編寫過濾請求的應用程式程式碼的需要。它在一個地方管理得很好。

最後,使用 HTTPS 可以協助保護您的連線並與 Yii 一起保護使用者。今年早些時候,我寫了一篇有關 Let's Encrypt 的文章 — 您也可以使用本教學為 Yii 應用程式安裝 HTTPS。

想了解更多內容嗎?

如果您有興趣閱讀有關這些主題的更詳細資料,Yii 1.x 框架提供了這些帖子。當然,它們比較舊,並且對 Yii 2 不太具體,但它們仍然有用。

  • 專題:安全性
  • 如何寫安全的 Yii 應用程式
  • Yii 安全擴充指南

結束中

我希望您喜歡我對 Yii2 的安全性概述。如果您將上述大部分或全部概念的各個方面整合到您的應用程式中,您應該擁有一個基本安全的 Web 服務。您可能需要查看我們的「使用 PHP 建立您的新創公司」系列,以了解其中一些安全實踐的實際實施情況。

請觀看我們的「使用 Yii2 程式設計」系列即將推出的教學課程,我們將繼續深入了解框架的不同面向。我歡迎功能和主題請求。您可以將它們發佈在下面的評論中,或在我的 Lookahead Consulting 網站上向我發送電子郵件。

#如果您想知道下一個 Yii2 教學何時發布,請在 Twitter 上關注我@reifman 或查看我的講師頁面。我的講師頁面將立即包含本系列的所有文章。

讓我們共同努力,讓編輯女神們開心。

相關連結

  • Yii 最佳安全實務
  • Yii 基礎安全類別
  • Yii2 開發者交流會

以上是Yii2編程:安全性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!