既然咱們有一個管理面板,天然須要進行驗證。幸運的是,Play已經提供了一個叫作Secure的模塊來幫助咱們。javascript
在yabe/conf/application.conf
啓動Secure模塊,而後重啓應用。css
# 導入secure模塊 module.secure=${play.path}/modules/secure
在重啓後,Play應該提示說模塊已被加載。html
Secure模塊提供一系列默認的路由。要導入這些路由,在/yabe/conf/routes
加入:java
# Import Secure routes * / module:secrue
這個模塊提供了一個controllers.Secure
控制器,它定義了全部所需的攔截器。固然咱們能夠繼承這個控制器,可是Java只支持單繼承,可能不能夠這麼作。jquery
除了直接繼承Secure
控制器,咱們也能夠給控制器加@With
註解來告訴Play啓動對應的攔截器:segmentfault
package controllers; import play.*; import play.mvc.*; @With(Secure.class) public class Posts extends CRUD { }
一樣處理Comments
,Users
和Tags
控制器。mvc
如今若是你想訪問管理面板,就會跳轉到登陸頁面。app
不過,如今不管你往用戶/密碼框填什麼,都會讓你經過。佈局
你能夠用應用提供的controllers.Secure.Security
實例來自定義驗證過程。經過繼承自該類,咱們能夠指定驗證用戶的方式。post
建立yabe/app/controllers/Security.java
,並重載authenticata()
方法:
package controllers; import models.*; public class Security extends Secure.Security { static boolean authenticate(String username, String password) { return true; } }
由於咱們已經在模型層實現了User對象,驗證方法的實現就很簡單了:
static boolean authenticate(String username, String password) { return User.connect(username, password) != null; }
如今前往http://localhost:9000/logout登出,而後嘗試以initial-data.yml
中的任意用戶登入,好比bob@gmail.com/secret
。
咱們經過CRUD模塊開啓了管理面板,但它跟博客的UI格格不入。因此咱們還須要實現另外一個管理面板。這個將給每一個做者發佈本身的文章的權限。固然,原來的管理面板仍是能夠留下來給超級管理員用。
讓咱們建立一個Admin
控制器:
package controllers; import play.*; import play.mvc.*; import java.util.*; import models.*; @With(Secure.class) public class Admin extends Controller { @Before static void setConnectedUser() { if(Security.isConnected()) { User user = User.find("byEmail", Security.connected()).first(); renderArgs.put("user", user.fullname); } } public static void index() { render(); } }
而後重構yabe/conf/routes
裏面的路由:
# Administration GET /admin/? Admin.index * /admin module:crud
記住路由文件中的順序是有確切含義的;排在前面的會比後面的優先匹配。因此Admin
的路由要放在映射到CRUD模塊的路由的前面。不然,/admin/
會被映射到CRUD.index
而不是Admin.index
。
如今在yabe/app/views/main.html
添加到控制器的連接:
… <ul id="tools"> <li> <a href="@{Admin.index()}">Log in to write something</a> </li> </ul> …
接下來是建立yabe/app/views/Admin/index.html
模板。讓咱們先從基礎開始:
Welcome ${user}!
如今,前往博客主頁,點擊「Log in to write something」連接,你應該到達新的管理面板:
好的開始!但由於管理面板將會有一系列新的頁面,咱們須要定義一個父模板。建立yabe/app/views/admin.html
:
<!DOCTYPE html> <html> <head> <title>Administration</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> #{get 'moreStyles' /} <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/main.css'}" /> <link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}" /> <script src="@{'/public/javascripts/jquery-1.4.2.min.js'}"></script> <script src="@{'/public/javascripts/jquery.tools-1.2.5.toolbox.expose.min.js'}"></script> </head> <body id="admin"> <div id="header"> <div id="logo"> yabe. <span>administration</span> </div> <ul id="tools"> <li> <a href="@{Secure.logout()}">Log out</a> </li> </ul> </div> <div id="main"> #{doLayout /} </div> <p id="footer"> Yabe is a (not so) powerful blog engine built with the <a href="http://www.playframework.org">Play framework</a> as a tutorial application. </p> </body> </html>
如你所見,它像是前面用在博客引擎上的模板。這裏替換了Log in連接成Log out,調用secure模塊提供的Secure
控制器的logout
action。
如今就把它用到yabe/app/views/Admin/index.html
模板:
#{extends 'admin.html' /} Welcome ${user}!
刷新!
嘗試下log out,它會讓你從新登陸:
咱們是用secure模塊的默認方法來處理登出。不過自定義也是十分簡單的,重寫controllers.Security
類中的onDisconnected()
方法便可:
static void onDisconnected() {
Application.index();
}
你能夠一樣重載onAuthenticated()
:
static void onAuthenticated() { Admin.index(); }
咱們有兩個管理面板:一個用於編輯者,另外一個用於管理員。如你曾見,User
模型有一個isAdmin
成員,表示一個用戶是否有管理員權限。
secure模塊不只提供了authentication
,還支持authorization
。在secure模塊中,這叫作 profiles
。要建立admin
身份(profile),你僅需重寫controllers.Security
中的 check()
。
static boolean check(String profile) { if("admin".equals(profile)) { return User.find("byEmail", connected()).<User>first().isAdmin; } return false; }
若是用戶具備管理員權限,咱們能夠提供一個管理員菜單。更新app/views/admin.html
來添加頂級菜單:
… <div id="main"> <ul id="adminMenu"> <li class="${request.controller == 'Admin' ? 'selected' : ''}"> <a href="@{Admin.index()}">My posts</a> </li> #{secure.check 'admin'} <li class="${request.controller == 'Posts' ? 'selected' : ''}"> <a href="@{Posts.list()}">Posts</a> </li> <li class="${request.controller == 'Tags' ? 'selected' : ''}"> <a href="@{Tags.list()}">Tags</a> </li> <li class="${request.controller == 'Comments' ? 'selected' : ''}"> <a href="@{Comments.list()}">Comments</a> </li> <li class="${request.controller == 'Users' ? 'selected' : ''}"> <a href="@{Users.list()}">Users</a> </li> #{/secure.check} </ul> #{doLayout /} </div> …
注意咱們用#{secure.check /}
標籤,只給admin
用戶展現菜單。
可是咱們的CRUD部分依然處於危險之中!若是用戶知道URL,他/她仍是能夠訪問它。咱們必須保護這些控制器。最簡單的方法是使用@Check
註解。舉個例子,對於Posts
控制器:
package controllers; import play.*; import play.mvc.*; @Check("admin") @With(Secure.class) public class Posts extends CRUD { }
一樣處理Tags
,Comments
和Users
控制器。如今做爲普通用戶(好比``)登陸。你應該看不到CRUD管理員連接。若是試圖訪問http://localhost:9000/admin/u...,你會獲得一個403 Forbidden響應。
當咱們使用基於CRUD的那個管理面板時,就沒法使用管理佈局了。由於CRUD模塊提供了本身的佈局。不過固然咱們能夠重載掉它。使用Play命令:
play crud:ov --layout
你會獲得一個/yabe/app/views/CRUD/layout.html
。來把它的內容替換掉,集成咱們的admin.html
佈局:
#{extends 'admin.html' /} #{set 'moreStyles'} <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/crud.css'}" /> #{/set} <div id="crud"> #{if flash.success} <div class="crudFlash flashSuccess"> ${flash.success} </div> #{/if} #{if flash.error || error} <div class="crudFlash flashError"> ${error ?: flash.error} </div> #{/if} <div id="crudContent"> #{doLayout /} </div> </div>
如你所見,咱們重用了crud.css
並使用get/set模板變量機制來融合admin.html
。如今看下CRUD模塊的管理面板,它應該跟管理佈局結合在一塊兒了:
管理面板的界面大致上已經完成了。最後要作的,是美化登陸界面。如常,從自定義默認的css開始吧。
play secure:ov --css
要想維持原來的css,咱們須要在頂部導入main.css
。在yabe/public/stylesheets/secure.css
頂部添加這一行:
@import url(main.css); …
加入這些到你的yabe/conf/messages
文件來自定義登陸界面信息:
secure.username=Your email: secure.password=Your password: secure.signin=Log in now