亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Yii2系列教程五:簡(jiǎn)單的用戶(hù)權(quán)限管理

livem / 1065人閱讀

摘要:原文來(lái)自上一篇文章講了用戶(hù)的注冊(cè),驗(yàn)證和登錄,這一篇文章按照約定來(lái)說(shuō)說(shuō)之中的用戶(hù)和權(quán)限控制。探尋上面的一些列設(shè)置和代碼更改,已經(jīng)實(shí)現(xiàn)了一小部分的用戶(hù)控制登錄的用戶(hù)才能發(fā)表。

  

原文來(lái)自: https://jellybool.com/post/programming-with-yii2-user-access-controls

上一篇文章講了用戶(hù)的注冊(cè),驗(yàn)證和登錄,這一篇文章按照約定來(lái)說(shuō)說(shuō)Yii2之中的用戶(hù)和權(quán)限控制。

你可以直接到Github下載源碼,以便可以跟上進(jìn)度,你也可以重頭開(kāi)始,一步一步按照這個(gè)教程來(lái)做。

  

鑒于本教材基于Yii2 Basic,所以對(duì)RBAC的詳細(xì)講解我后面再多帶帶出文章來(lái)說(shuō)說(shuō)吧,這里主要是簡(jiǎn)單地說(shuō)一說(shuō)權(quán)限控制

上一篇文章所實(shí)現(xiàn)的功能還比較簡(jiǎn)單,可以發(fā)一條狀態(tài),但是不知道你注意到?jīng)]有,如果是沒(méi)有注冊(cè)的用戶(hù)也可以使用我們的應(yīng)用(類(lèi)似小微博)來(lái)發(fā)狀態(tài),這是不符合情理的。正確的做法是在用戶(hù)沒(méi)有注冊(cè),登錄之前,我們甚至都不應(yīng)該給沒(méi)有注冊(cè)的用戶(hù)看到我們創(chuàng)建狀態(tài)的頁(yè)面,即是http://localhost:8999/status/create就不應(yīng)該讓游客看到,更不用說(shuō)編輯和刪除一條狀態(tài)(status)了。

權(quán)限控制

什么是權(quán)限控制?個(gè)人覺(jué)得在一個(gè)Web應(yīng)用當(dāng)中,有以下幾種常見(jiàn)的角色和權(quán)限控制:

1. 游客,也就是沒(méi)有注冊(cè)的用戶(hù),一般這個(gè)權(quán)限是最小的,對(duì)于一些需要登錄訪(fǎng)問(wèn)的頁(yè)面沒(méi)有訪(fǎng)問(wèn)權(quán)限


2. 用戶(hù),這里的用戶(hù)特指注冊(cè)用戶(hù),注冊(cè)過(guò)后的用戶(hù)一般可以使用整個(gè)web應(yīng)用的主要功能,比如我們這里的發(fā)表一條狀態(tài)(status)

3. 作者,這個(gè)不知道確切應(yīng)該使用什么名詞來(lái)描述,作者是在用戶(hù)注冊(cè)之后的一個(gè)權(quán)限判斷,比如A發(fā)表的status狀態(tài),B君不能進(jìn)行編輯,刪除等,反之亦然。

4. 管理員,這里的管理員通常會(huì)是應(yīng)用的開(kāi)發(fā)者(所有者,或者應(yīng)該這么說(shuō)),幾乎可以說(shuō)是對(duì)站點(diǎn)的所有權(quán)限都有

Yii2自帶的權(quán)限控制默認(rèn)只支持兩個(gè)角色:

guest(游客,沒(méi)有登錄的,用?表示)

authenticated (登錄了的,用@表示)

在這里我們需要實(shí)現(xiàn)的是對(duì)這兩種不同的角色指定不同的訪(fǎng)問(wèn)權(quán)限,就是為他們分配不同的可以訪(fǎng)問(wèn)的控制器或者方法。

目前我們?nèi)绻苯狱c(diǎn)擊導(dǎo)航欄的Status,我們還是可以在沒(méi)有登錄的情況之下進(jìn)行發(fā)表狀態(tài)(status),所以我們需要改一下我們的代碼和邏輯,Yii2在這方面的控制做得非常好,其實(shí)實(shí)現(xiàn)這個(gè)我們只需要修改一下StatusController.php里面的behaviors()方法而已,在這里面加入一段access設(shè)置:

```
public function behaviors()
    {
        return [
            "verbs" => [
                "class" => VerbFilter::className(),
                "actions" => [
                    "delete" => ["post"],
                ],
            ],
            "access" => [
                "class" => AccessControl::className(),
                "only" => ["index","create","update","view"],
                "rules" => [
                    // allow authenticated users
                    [
                        "allow" => true,
                        "roles" => ["@"],
                    ],
                    // everything else is denied
                ],
            ],
        ];
    }

```

加上access這一段之后,我們?cè)俅吸c(diǎn)擊Status,Yii2就會(huì)將未登錄的我重定向到登錄頁(yè)面。

而且,這個(gè)時(shí)候,一旦你登入進(jìn)去,Yii會(huì)默認(rèn)自動(dòng)跳轉(zhuǎn)到上一個(gè)url,也就是我們剛剛點(diǎn)擊的status/index。

添加映射關(guān)系

用戶(hù)一旦登錄進(jìn)來(lái)之后,我們就可以通過(guò)下面這行代碼來(lái)獲取用戶(hù)的id了:

```
Yii::$app->user->getId();

```

一旦用戶(hù)的id獲取到,我們可以做的事就很多了。這里我們先來(lái)將一條狀態(tài)和用戶(hù)聯(lián)系起來(lái),也就是添加用戶(hù)與說(shuō)說(shuō)的映射關(guān)系。要實(shí)現(xiàn)這個(gè)目標(biāo)我們需要先修改我們的數(shù)據(jù)表(體驗(yàn)一下當(dāng)初設(shè)計(jì)數(shù)據(jù)表考慮不周全的情況):

```
./yii migrate/create extend_status_table_for_created_by
Yii Migration Tool (based on Yii v2.0.6)

Create new migration "/Users/jellybool/Desktop/helloYii/migrations/m150806_034325_extend_status_table_for_created_by.php"? (yes|no) [no]:yes

New migration created successfully.

```

打開(kāi)對(duì)應(yīng)的migration文件,編輯up()down()方法,如果你想加入數(shù)據(jù)庫(kù)的事務(wù)管理功能,你可以使用safeUp()safeDown()方法

```
public function up()
    {
        $this->addColumn("{{%status}}","created_by",Schema::TYPE_INTEGER." NOT NULL");
        $this->addForeignKey("fk_status_created_by", "{{%status}}", "created_by", "{{%user}}", "id", "CASCADE", "CASCADE");
    }

public function down()
{
    $this->dropForeignKey("fk_status_created_by","{{%status}}");
    $this->dropColumn("{{%status}}","created_by");
}

```

我們需要為status表添加一個(gè)created_by字段,并且將它跟user表的id設(shè)為外鍵關(guān)系。

  

如果你在status表里面有一條數(shù)據(jù)記錄,你需要先刪除這一條記錄,不然可能會(huì)報(bào)錯(cuò)。

執(zhí)行migrate/up:

```
./yii migrate/up
Yii Migration Tool (based on Yii v2.0.6)

Total 1 new migration to be applied:
    m150806_034325_extend_status_table_for_created_by

Apply the above migration? (yes|no) [no]:yes
*** applying m150806_034325_extend_status_table_for_created_by
    > add column created_by integer NOT NULL to table {{%status}} ... done (time: 0.032s)
    > add foreign key fk_status_created_by: {{%status}} (created_by) references {{%user}} (id) ... done (time: 0.014s)
*** applied m150806_034325_extend_status_table_for_created_by (time: 0.059s)

```

數(shù)據(jù)表的外鍵設(shè)置好之后,我們就可以來(lái)聲明StatusUser的關(guān)系了,不過(guò)在開(kāi)始之前需要修改一下User.php里面的內(nèi)容:

```


直接將原來(lái)的User模型的代碼都刪掉,只需要我們上面的代碼就可以了,因?yàn)槲覀兪褂昧薡ii2-User,
這里就是使用dektriumusermodelsUser這個(gè)模型,然后修改一下我們的config/web.php,再我們之前的user中加入幾行代碼:

```
 "modules" => [
        "user" => [
            "class" => "dektriumuserModule",
            "confirmWithin" => 21600,
            // add the following 3 lines
            "modelMap" => [
                "User" => "appmodelsUser",
            ],

            "cost" => 12,
            "admins" => ["admin"]
        ],
    ],

```

這樣之后,我們的User和Status的對(duì)應(yīng)關(guān)系就會(huì)建立起來(lái)。

然后我們?cè)赟tatus.php寫(xiě)上以下的說(shuō)明:

```
public function getUser()
    {
        return $this->hasOne(User::className(), ["id" => "created_by"]);
    }

```

這里聲明的映射關(guān)系為hasOne,也就是說(shuō),一條狀態(tài)status(說(shuō)說(shuō))對(duì)應(yīng)一個(gè)用戶(hù)(User),我們通過(guò)["id" => "created_by"]來(lái)指定外鍵映射。

有了Status和User的對(duì)應(yīng)關(guān)系之后,我們需要在用戶(hù)發(fā)表狀態(tài)的時(shí)候?qū)⒂脩?hù)的id保存到Statuscreated_by這一個(gè)字段中,所以我們需要在StatusController中的actionCreate方法中加上一行代碼:

```
if ($model->load(Yii::$app->request->post())) {
    $model->created_by = Yii::$app->user->getId();//add this line
    $model->created_at = time();
    $model->updated_at = time();
    if ($model->save()) {
        return $this->redirect(["view", "id" => $model->id]);
    }
}

```

這里需要確認(rèn)的是,你需要保證create方法只能是登錄進(jìn)來(lái)的用戶(hù)才能訪(fǎng)問(wèn)觸發(fā)。

為了更好地展示一條狀態(tài)stutas的信息,我們修改一下展示狀態(tài)的視圖文件:status/view.php :

```
 $model,
        "attributes" => [
            "id",
            "user.email", // add this line
            "message:ntext",
            "created_by", // add this line
            "permissions",
            "created_at",
            "updated_at",
        ],
    ]) ?>

```

上面的user.email中的user其實(shí)是觸發(fā)Status::getUser()這個(gè)方法。

這樣一刷新之后,我們就可以看到創(chuàng)建這條狀態(tài)的用戶(hù)idemail了。

探尋RBAC

上面的一些列設(shè)置和代碼更改,已經(jīng)實(shí)現(xiàn)了一小部分的用戶(hù)控制:登錄的用戶(hù)才能發(fā)表status。然而這還不能滿(mǎn)足我們?cè)谌粘J褂玫男枨?,比如我們現(xiàn)在怎么確定一個(gè)用戶(hù)能不能對(duì)某條狀態(tài)進(jìn)行修改和刪除?或者說(shuō),管理員的角色在哪里體現(xiàn)呢?現(xiàn)在貌似都是平等的角色,相同的權(quán)限,對(duì)于登錄的用戶(hù)來(lái)說(shuō)。

鑒于官方文檔或者很多關(guān)于Yii2 RBAC的資料都是基于Yii2 Advanced Template,而我們一開(kāi)始使用的是Yii2 Basic Template,并且我們也引入Yii2-User,所以這里我們嘗試來(lái)自己實(shí)現(xiàn)一點(diǎn)點(diǎn)的用戶(hù)權(quán)限控制。

首先我們需要在User中定義一些跟角色(role)相關(guān)的規(guī)定,比如根據(jù)不同的用戶(hù)角色來(lái)賦予不同的常量:

```
class User extends BaseUser {
    const ROLE_USER = 10;
    const ROLE_MODERATOR = 20;
    const ROLE_ADMIN = 30;

}

```

上面的代碼寫(xiě)在User模型里面,這里定義了三種角色,ROLE_USER,ROLE_MODERATOR,ROLE_ADMINUSER可以發(fā)表狀態(tài),MODERATOR可以修改但是不可以刪除,ADMIN可以修改和刪除。

然后在helloYii/目錄之下創(chuàng)建一個(gè)components/目錄,里面新建一個(gè)AccessRule.php文件:

roles) === 0) {
            return true;
        }
        foreach ($this->roles as $role) {
            if ($role === "?") {
                if ($user->getIsGuest()) {
                    return true;
                }
            } elseif ($role === User::ROLE_USER) {
                if (!$user->getIsGuest()) {
                    return true;
                }
                // Check if the user is logged in, and the roles match
            } elseif (!$user->getIsGuest() && $role === $user->identity->role) {
                return true;
            }
        }

        return false;
    }
}

這里就直接借用Yii2自帶的yiifiltersAccessRule來(lái)控制權(quán)限規(guī)則。但是由于Yii2-User在創(chuàng)建user數(shù)據(jù)表的時(shí)候并沒(méi)有role這個(gè)字段,所以我們需要手動(dòng)添加,你可以直接在mysql敲命令行,或者也可以通過(guò)數(shù)據(jù)庫(kù)管理工具來(lái)添加。

最后更新一下我們的StatusController.php文件,這里的behaviors()方法會(huì)做出一些調(diào)整:

 [
                "class" => VerbFilter::className(),
                "actions" => [
                    "delete" => ["post"],
                ],
            ],
            "access" => [
                "class" => AccessControl::className(),
                // We will override the default rule config with the new AccessRule class
                "ruleConfig" => [
                    "class" => AccessRule::className(),
                ],
                "only" => ["index","create", "update", "delete"],
                "rules" => [
                    [
                        "actions" => ["index","create"],
                        "allow" => true,
                        // Allow users, moderators and admins to create
                        "roles" => [
                            User::ROLE_USER,
                            User::ROLE_MODERATOR,
                            User::ROLE_ADMIN
                        ],
                    ],
                    [
                        "actions" => ["update"],
                        "allow" => true,
                        // Allow moderators and admins to update
                        "roles" => [
                            User::ROLE_MODERATOR,
                            User::ROLE_ADMIN
                        ],
                    ],
                    [
                        "actions" => ["delete"],
                        "allow" => true,
                        // Allow admins to delete
                        "roles" => [
                            User::ROLE_ADMIN
                        ],
                    ],
                ],
            ],
        ];
    }

我們上面根據(jù)不同等級(jí)的用戶(hù)賦予不同的訪(fǎng)問(wèn)權(quán)限,這時(shí)候,如果你先logout出來(lái),再登錄回去,你還是可以看到這些status,但是一旦你點(diǎn)擊
delete(刪除按鈕),你將會(huì)看到一個(gè)報(bào)錯(cuò)的頁(yè)面:

我們手動(dòng)創(chuàng)建的role是成功,但是我們?cè)趺唇o一個(gè)注冊(cè)的用戶(hù)默認(rèn)的權(quán)限呢,我們這里就是想實(shí)現(xiàn)在新用戶(hù)注冊(cè)的時(shí)候賦予用戶(hù)ROLE_USER的角色和權(quán)限。由于Yii2-User是在vendordektriumyii2-usermodelsRegistrationForm.php這個(gè)文件里面進(jìn)行創(chuàng)建新的用戶(hù)的,我門(mén)這里只要修改一個(gè)小地方,找到register()方法:

  public function register()
    {
        if ($this->validate()) {
            $user = $this->module->manager->createUser([
                "email"    => $this->email,
                "username" => $this->username,
                "password" => $this->password,
                "role"=>10, // add this line User::ROLE_USER;                
            ]);

            return $user->register();
        }

        return false;
    }

添加"role"=>10就可以了。

如果你想證明一下我們的權(quán)限是否正確,你可以手動(dòng)修改數(shù)據(jù)庫(kù)中的role字段的數(shù)值,然后在進(jìn)行修改和刪除等操作,看看是否可以正確運(yùn)行。

權(quán)限控制其實(shí)可以說(shuō)是Yii2的一大特色和亮點(diǎn),在這里可能并沒(méi)有說(shuō)得很清晰,只是簡(jiǎn)單地實(shí)現(xiàn)了一些規(guī)則,有機(jī)會(huì)借助Yii2 Advanced Template來(lái)實(shí)現(xiàn)一下。

源碼會(huì)放在 Github:https://github.com/JellyBool/helloYii

下一節(jié)

下一節(jié)嘗試集成一個(gè)編輯器和做一下url的美化,內(nèi)容應(yīng)該會(huì)比較簡(jiǎn)單

Happy Hacking

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/21044.html

相關(guān)文章

  • Yii2系列教程七:Behaviors And Validations

    摘要:原文來(lái)自這一篇文章的開(kāi)頭就無(wú)需多言了,緊接著上一篇的內(nèi)容和計(jì)劃,這一篇我們來(lái)說(shuō)說(shuō)的和。,那既然這樣,我們就來(lái)實(shí)現(xiàn)一下唄。所以我們首先需要將表中的幾條數(shù)據(jù)刪掉。下一節(jié)再詳細(xì)講講吧,這一節(jié)寫(xiě)下來(lái)貌似要說(shuō)的實(shí)在有點(diǎn)多。 原文來(lái)自:https://jellybool.com/post/programming-with-yii2-behaviors-and-validat... 這一篇...

    fasss 評(píng)論0 收藏0
  • Yii2系列教程四:實(shí)現(xiàn)用戶(hù)注冊(cè),驗(yàn)證,登錄

    摘要:開(kāi)始使用郵箱配置好了之后,我們就可以開(kāi)始使用了,首先我們來(lái)修改一下我們的導(dǎo)航欄,因?yàn)槲覀兿雽?shí)現(xiàn)的就是我們常??吹降脑趯?dǎo)航欄的右側(cè)的注冊(cè)和登錄按鈕。 原文來(lái)自: https://jellybool.com/post/programming-with-yii2-integrating-user-regi... 本來(lái)打算昨晚寫(xiě)的這篇教程,但是忙著約會(huì)去了,所以現(xiàn)在補(bǔ)上吧。 上一篇...

    boredream 評(píng)論0 收藏0
  • Yii2系列教程六:集成編輯器

    摘要:而這些問(wèn)題目前的最好解決方案就是集成一個(gè)編輯器,鑒于大家這里不是指程序員都是喜歡所見(jiàn)即所得,所以,這里我主要是演示怎么集成所見(jiàn)即所得的富文本編輯器。 原文來(lái)自: https://jellybool.com/post/programming-with-yii2-rich-text-input-with-redactor 首先,很慚愧的是,前幾天都出去外面玩了,沒(méi)有及時(shí)更新教程,...

    xiaochao 評(píng)論0 收藏0
  • Yii2系列教程二:MVC Forms 和 Layouts

    摘要:而且很明顯地,我們可以看到,一旦輸入框在失去焦點(diǎn)的時(shí)候,如果里面沒(méi)有輸入任何內(nèi)容,每個(gè)輸入框就會(huì)有相應(yīng)的錯(cuò)誤提示,用戶(hù)體驗(yàn)很不錯(cuò)。 原文來(lái)自: https://jellybool.com/post/programming-with-yii2-exploring-mvc-forms-a... 上一篇文章我們簡(jiǎn)單地實(shí)現(xiàn)了Yii2框架安裝和Hello World,而在這一篇文章當(dāng)中...

    ThreeWords 評(píng)論0 收藏0
  • yii2搭建完美后臺(tái)并實(shí)現(xiàn)rbac權(quán)限控制實(shí)例教程

    摘要:利用渲染后臺(tái)模板后臺(tái)的模板我們采用利用插播一曲是一個(gè)完全響應(yīng)管理模板。基于框架,易定制模板。適合多種屏幕分辨率,從小型移動(dòng)設(shè)備到大型臺(tái)式機(jī)。內(nèi)置了多個(gè)頁(yè)面,包括儀表盤(pán)郵箱日歷鎖屏登錄及注冊(cè)錯(cuò)誤錯(cuò)誤等頁(yè)面。 作者:白狼 出處:http://www.manks.top/yii2_fra... 本文版權(quán)歸作者,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保...

    neu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<