摘要:原文來自上一篇文章講了用戶的注冊,驗證和登錄,這一篇文章按照約定來說說之中的用戶和權限控制。探尋上面的一些列設置和代碼更改,已經實現了一小部分的用戶控制登錄的用戶才能發表。
原文來自: https://jellybool.com/post/programming-with-yii2-user-access-controls
上一篇文章講了用戶的注冊,驗證和登錄,這一篇文章按照約定來說說Yii2之中的用戶和權限控制。
你可以直接到Github下載源碼,以便可以跟上進度,你也可以重頭開始,一步一步按照這個教程來做。
鑒于本教材基于Yii2 Basic,所以對RBAC的詳細講解我后面再多帶帶出文章來說說吧,這里主要是簡單地說一說權限控制
上一篇文章所實現的功能還比較簡單,可以發一條狀態,但是不知道你注意到沒有,如果是沒有注冊的用戶也可以使用我們的應用(類似小微博)來發狀態,這是不符合情理的。正確的做法是在用戶沒有注冊,登錄之前,我們甚至都不應該給沒有注冊的用戶看到我們創建狀態的頁面,即是http://localhost:8999/status/create就不應該讓游客看到,更不用說編輯和刪除一條狀態(status)了。
權限控制什么是權限控制?個人覺得在一個Web應用當中,有以下幾種常見的角色和權限控制:
1. 游客,也就是沒有注冊的用戶,一般這個權限是最小的,對于一些需要登錄訪問的頁面沒有訪問權限 2. 用戶,這里的用戶特指注冊用戶,注冊過后的用戶一般可以使用整個web應用的主要功能,比如我們這里的發表一條狀態(status) 3. 作者,這個不知道確切應該使用什么名詞來描述,作者是在用戶注冊之后的一個權限判斷,比如A發表的status狀態,B君不能進行編輯,刪除等,反之亦然。 4. 管理員,這里的管理員通常會是應用的開發者(所有者,或者應該這么說),幾乎可以說是對站點的所有權限都有
Yii2自帶的權限控制默認只支持兩個角色:
guest(游客,沒有登錄的,用?表示)
authenticated (登錄了的,用@表示)
在這里我們需要實現的是對這兩種不同的角色指定不同的訪問權限,就是為他們分配不同的可以訪問的控制器或者方法。
目前我們如果直接點擊導航欄的Status,我們還是可以在沒有登錄的情況之下進行發表狀態(status),所以我們需要改一下我們的代碼和邏輯,Yii2在這方面的控制做得非常好,其實實現這個我們只需要修改一下StatusController.php里面的behaviors()方法而已,在這里面加入一段access設置:
``` 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這一段之后,我們再次點擊Status,Yii2就會將未登錄的我重定向到登錄頁面。
而且,這個時候,一旦你登入進去,Yii會默認自動跳轉到上一個url,也就是我們剛剛點擊的status/index。
添加映射關系用戶一旦登錄進來之后,我們就可以通過下面這行代碼來獲取用戶的id了:
``` Yii::$app->user->getId(); ```
一旦用戶的id獲取到,我們可以做的事就很多了。這里我們先來將一條狀態和用戶聯系起來,也就是添加用戶與說說的映射關系。要實現這個目標我們需要先修改我們的數據表(體驗一下當初設計數據表考慮不周全的情況):
``` ./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. ```
打開對應的migration文件,編輯up()和down()方法,如果你想加入數據庫的事務管理功能,你可以使用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表添加一個created_by字段,并且將它跟user表的id設為外鍵關系。
如果你在status表里面有一條數據記錄,你需要先刪除這一條記錄,不然可能會報錯。
執行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) ```
數據表的外鍵設置好之后,我們就可以來聲明Status和User的關系了,不過在開始之前需要修改一下User.php里面的內容:
```直接將原來的User模型的代碼都刪掉,只需要我們上面的代碼就可以了,因為我們使用了Yii2-User,
這里就是使用dektriumusermodelsUser這個模型,然后修改一下我們的config/web.php,再我們之前的user中加入幾行代碼:``` "modules" => [ "user" => [ "class" => "dektriumuserModule", "confirmWithin" => 21600, // add the following 3 lines "modelMap" => [ "User" => "appmodelsUser", ], "cost" => 12, "admins" => ["admin"] ], ], ```這樣之后,我們的User和Status的對應關系就會建立起來。
然后我們在Status.php寫上以下的說明:
``` public function getUser() { return $this->hasOne(User::className(), ["id" => "created_by"]); } ```這里聲明的映射關系為hasOne,也就是說,一條狀態status(說說)對應一個用戶(User),我們通過["id" => "created_by"]來指定外鍵映射。
有了Status和User的對應關系之后,我們需要在用戶發表狀態的時候將用戶的id保存到Status的created_by這一個字段中,所以我們需要在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]); } } ```這里需要確認的是,你需要保證create方法只能是登錄進來的用戶才能訪問觸發。
為了更好地展示一條狀態stutas的信息,我們修改一下展示狀態的視圖文件:status/view.php :
``` = DetailView::widget([ "model" => $model, "attributes" => [ "id", "user.email", // add this line "message:ntext", "created_by", // add this line "permissions", "created_at", "updated_at", ], ]) ?> ```上面的user.email中的user其實是觸發Status::getUser()這個方法。
這樣一刷新之后,我們就可以看到創建這條狀態的用戶id和email了。
探尋RBAC上面的一些列設置和代碼更改,已經實現了一小部分的用戶控制:登錄的用戶才能發表status。然而這還不能滿足我們在日常使用的需求,比如我們現在怎么確定一個用戶能不能對某條狀態進行修改和刪除?或者說,管理員的角色在哪里體現呢?現在貌似都是平等的角色,相同的權限,對于登錄的用戶來說。
鑒于官方文檔或者很多關于Yii2 RBAC的資料都是基于Yii2 Advanced Template,而我們一開始使用的是Yii2 Basic Template,并且我們也引入Yii2-User,所以這里我們嘗試來自己實現一點點的用戶權限控制。
首先我們需要在User中定義一些跟角色(role)相關的規定,比如根據不同的用戶角色來賦予不同的常量:
``` class User extends BaseUser { const ROLE_USER = 10; const ROLE_MODERATOR = 20; const ROLE_ADMIN = 30; } ```上面的代碼寫在User模型里面,這里定義了三種角色,ROLE_USER,ROLE_MODERATOR,ROLE_ADMIN,USER可以發表狀態,MODERATOR可以修改但是不可以刪除,ADMIN可以修改和刪除。
然后在helloYii/目錄之下創建一個components/目錄,里面新建一個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來控制權限規則。但是由于Yii2-User在創建user數據表的時候并沒有role這個字段,所以我們需要手動添加,你可以直接在mysql敲命令行,或者也可以通過數據庫管理工具來添加。
最后更新一下我們的StatusController.php文件,這里的behaviors()方法會做出一些調整:
[ "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 ], ], ], ], ]; }我們上面根據不同等級的用戶賦予不同的訪問權限,這時候,如果你先logout出來,再登錄回去,你還是可以看到這些status,但是一旦你點擊
delete(刪除按鈕),你將會看到一個報錯的頁面:我們手動創建的role是成功,但是我們怎么給一個注冊的用戶默認的權限呢,我們這里就是想實現在新用戶注冊的時候賦予用戶ROLE_USER的角色和權限。由于Yii2-User是在vendordektriumyii2-usermodelsRegistrationForm.php這個文件里面進行創建新的用戶的,我門這里只要修改一個小地方,找到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就可以了。
如果你想證明一下我們的權限是否正確,你可以手動修改數據庫中的role字段的數值,然后在進行修改和刪除等操作,看看是否可以正確運行。
權限控制其實可以說是Yii2的一大特色和亮點,在這里可能并沒有說得很清晰,只是簡單地實現了一些規則,有機會借助Yii2 Advanced Template來實現一下。
源碼會放在 Github:https://github.com/JellyBool/helloYii
下一節下一節嘗試集成一個編輯器和做一下url的美化,內容應該會比較簡單
Happy Hacking
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21044.html
摘要:原文來自這一篇文章的開頭就無需多言了,緊接著上一篇的內容和計劃,這一篇我們來說說的和。,那既然這樣,我們就來實現一下唄。所以我們首先需要將表中的幾條數據刪掉。下一節再詳細講講吧,這一節寫下來貌似要說的實在有點多。 原文來自:https://jellybool.com/post/programming-with-yii2-behaviors-and-validat... 這一篇...
摘要:開始使用郵箱配置好了之后,我們就可以開始使用了,首先我們來修改一下我們的導航欄,因為我們想實現的就是我們常常看到的在導航欄的右側的注冊和登錄按鈕。 原文來自: https://jellybool.com/post/programming-with-yii2-integrating-user-regi... 本來打算昨晚寫的這篇教程,但是忙著約會去了,所以現在補上吧。 上一篇...
摘要:而這些問題目前的最好解決方案就是集成一個編輯器,鑒于大家這里不是指程序員都是喜歡所見即所得,所以,這里我主要是演示怎么集成所見即所得的富文本編輯器。 原文來自: https://jellybool.com/post/programming-with-yii2-rich-text-input-with-redactor 首先,很慚愧的是,前幾天都出去外面玩了,沒有及時更新教程,...
摘要:而且很明顯地,我們可以看到,一旦輸入框在失去焦點的時候,如果里面沒有輸入任何內容,每個輸入框就會有相應的錯誤提示,用戶體驗很不錯。 原文來自: https://jellybool.com/post/programming-with-yii2-exploring-mvc-forms-a... 上一篇文章我們簡單地實現了Yii2框架安裝和Hello World,而在這一篇文章當中...
摘要:利用渲染后臺模板后臺的模板我們采用利用插播一曲是一個完全響應管理模板。基于框架,易定制模板。適合多種屏幕分辨率,從小型移動設備到大型臺式機。內置了多個頁面,包括儀表盤郵箱日歷鎖屏登錄及注冊錯誤錯誤等頁面。 作者:白狼 出處:http://www.manks.top/yii2_fra... 本文版權歸作者,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保...
閱讀 2740·2021-09-02 15:11
閱讀 912·2019-08-26 18:18
閱讀 1872·2019-08-26 11:57
閱讀 3325·2019-08-23 16:59
閱讀 1998·2019-08-23 16:51
閱讀 2310·2019-08-23 16:11
閱讀 3129·2019-08-23 14:58
閱讀 1112·2019-08-23 11:34