2008年11月10日 星期一

Merb-Auth (1) 快速上手

幾乎每個 WebApp 一開始要都是先把登入登出做起來吧?

Merb-Auth 是 Merb 預設的 Authentication framework,非常的彈性,和一般 Rails 的做法(對,就是 restful_authetication 和他的徒子徒孫),相當的不同。MerbAuth 它只做一件事:登入。所以有關使用者管理、像是註冊,認證email、重設密碼之類的,事通通要你自己來

這一篇文章我們先完全用 Merb 初始的設定,來完成一個有登入功能的 HelloWorld,下篇我們再慢慢解釋其中的原理,如何做各種的設定。

首先,產生一個新的 merb app
$ merb-gen app hello_world
$ cd hello_world
merb-gen 出來的程式,預設就會開啟 Merb-Auth 的功能,使用 username/password 的認證方式,它會假設你要用 User 這個 model,所以就幫你建好在 app/models/user.rb 裡了。
$ rake db:automigrate
這會將 User model 的 schema 寫到 db 裡。因為 MerbAuth 並沒有註冊的功能,所以我們先手動建立一個 user:
$ merb -i
>> u = User.new(:login => "new_user")
>> u.password = u.password_confirmation = "12345"
>> u.save
接下來我們隨便產生一個頁面,就叫它 /hello/index 吧:
$ merb-gen controller hello
然後修改 config/routes.rb,把首頁指到 /hello/index 去:
Merb::Router.prepare do
slice(:merb_auth_slice_password, :name_prefix => nil, :path_prefix => "")
authenticate do
match('/').to(:controller => 'hello', :action =>'index')
end
end
用 authenticate do ... end 將 route 包住,就會讓它必需要登入才能看到。
這樣就好了!啟動 server
$ merb
用 browser 開啟 http://localhost:4000/ 就會看到登入的畫面。
輸入正確的 username/password (我們的例子中是 new_user/12345) 後,就會看到 hello/index 的內容。

登入後,我們可以用 session.user 取得 user object。讓我們修改一下 app/view/hello/index.html.erb,可以看到登入者的名字,順便也把登出的 link 做上去:
<div>Hello!!! <%= session.user.login %></div>
<%= link_to "登出", url(:logout) %>
除了用 authenticate 來包住 route 之中,也可以用 before filter 的方式,在 app/controllers/hello.rb 再加上一個 action:
before :ensure_authenticated, :only => 'wazzap'
def wazzap
"wazzap!! #{session.user.login}"
end
還有那個登入的 form 實在是太醜了!想要改變的話,可以寫這個檔案 app/views/exceptions/unauthenticated.html.erb:

<h3>還是很醜的登入 FORM</h3>

<div>
<%= session[:return_to].inspect %>
<%= error_messages_for session.authentication %>
<% @login_param = Merb::Authentication::Strategies::Basic::Base.login_param %>
<% @password_param = Merb::Authentication::Strategies::Basic::Base.password_param %>
<form action="<%= slice_url(:merb_auth_slice_password, :perform_login) %>" method="POST" accept-charset="utf-8">
<input type="hidden" name="_method" value="PUT" />
<div class="formRow">
<label>帳號:
<input type="text" name="<%= @login_param.to_s %>" value="" id="<%= @login_param.to_s %>">
</label>
</div> <!-- close: formRow -->
<div class="formRow">
<label>密碼:
<input type="password" name="<%= @password_param.to_s %>" value="" id="<%= @password_param.to_s %>">
</label>
</div> <!-- close: formRow -->
<div class="formRow">
<input type="submit" name="Submit" value="登入" id="Submit">
</div> <!-- close: formRow -->
</form>
</div>
下一篇我們會解釋為什麼這個 form 的位置這麼的奇怪。

沒有留言: