iT邦幫忙

DAY 5
11

Rails 的簡單任務系列 第 5

[RoR] 簡單完成登入登出的授權機制

在未接觸 RoR 之前,要寫一個網站的認證機制,對我來說真的很頭大,要搞清楚 Sessions 怎麼運作,cookies怎麼去運用,好多細節要去留意到;而 RoR 中的 restful_authentication 的 plugin 真的用幾行就搞定,可以讓自己的心力放在網站要怎麼去動作的議題上。
restful_authentication的簡介及安裝
要實作一個可新增帳號、登入及登出的授權機制,真的蠻麻煩;而這個restful_authentication都先把必要而共通需要的每個動作都作掉了,這篇的screencast http://railscasts.com/episodes/67,實在是簡潔而有效的教學,照著指令操作就完成了登出登入的基本功能,

cd test1
#安裝 restful_authentication 的 plugin
./script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/
# 產生 user 的 model及 table 的欄位定義,並做出 users, sessions 的controller及views
script/generate authenticated user sessions
# 做到資料庫的table
rake db:migrate

上述的第四行,是最簡單的帳號政策,可以在網頁上直接註冊新的帳號,該帳號密碼即可使用;若再加上參數 --include-activation ,則會為該帳號產生一驗證碼,透過 ActionMailer 寄到註冊時所提供的email地址,從email中點選其連結才生效該帳號;再加上 --stateful 這參數,可讓帳號有不同的狀態:像是有註冊但未啟用(:pending)、不能登入但可用來做mailing list之類的用途(:pasive)、暫時停用(:suspended)、帳號雖刪除但id仍留著,而其登入名稱及email可再被使用(:deleted)、啟用(:active)等。(參閱http://www.vaporbase.com/postings/stateful\_authentication)

如果又需要把使用者區分成不同的角色或群組,而允許做所指定的動作的話,就需要參閱Restful Authentication with all the bells and whistles這篇文章指到最新版的文章來實作。

貼上幾行就可運作
可以用現成的這兩個註冊、登入畫面:
app/views/sessions/new.html.erb 即是登入帳號密碼的 form template
app/views/users/new.html.erb 是註冊新帳號密碼 email 的 form template

#在 config/routes.rb 裡加入即可用
# 額外加這一行,可以讓第三日的 blog 的 controller 的 index 畫面當首面,可不用多打路徑就出現
map.root :controller => "blog", :action => "index"
# 以下做出註冊、登入、登出的路徑
map.signup '/signup', :controller => 'users', :action => 'new'
map.login  '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'

這樣 http://sitename/signup 就可註冊,…以此類推。

以「第三日」為例,若要在articles上加上此認證機制,可先在 app/views/layouts/articles.html.erb 加上

# 在  之下加入這幾行
<% if logged_in? %>
您是:<%= current_user.login -%> || <%= link_to '登出', logout_url -%>
<% else -%>
未登入
<% end -%>
<p style="color: green"><%= flash[:notice] %></p>

可讓 http://sitename/articles/\* 的每頁上方有登出入的狀態。
如果上述的第四行「未登入」,也可取代為連結到預設的 登入 網頁或者直接畫出 登入的 form :

# 以 連結 來取代
<%= link_to '到登入畫面', login_url -%>
# 或者以 form 來取代
<% form_tag session_path do -%>
<label for="login">帳號</label><%= text_field_tag 'login',nil,:size => 10 %>
<label for="password">密碼</label><%= password_field_tag 'password',nil ,:size => 10 %>
<%= submit_tag "登入", :name => nil %>
<% end %>

當執行的時候會出現 undefined method `logged_in?' for #<ActionView::Base:0x7f1a1d38c230> 這樣的錯誤訊息,所以要把 include AuthenticatedSystem 這一行字加到controller裡面,如果加在 app/controllers/application.rb 裡,則 controller 中就會把認證的function都讀進來,若不要所有的 controller 需要做認證動作的話,就只要加在該controller之中。

#在 app/controllers/application.rb 加入
class ApplicationController < ActionController::Base
include AuthenticatedSystem
...
end
# 或只在 app/controllers/articles_controller.rb 裡
class ArticlesController < ApplicationController
include AuthenticatedSystem
# 所有動作都需先登入
before_filter :login_required
# 或 列舉出需要登入的action
before_filter :login_required, :only => [ :new, :create, :edit, :update, :destroy ]
# 或 除了這兩個action外,其他動作都需登入才能執行
before_filter :login_required, :except => [ :index, :show ]
...
end

上述只是讓 controller 認得怎麼做認證及相關的變數,而要讓action經過認證才可被執行的話,就要在該controller上加上上述的10或12或14行,對於要未登入而要做需授權的動作,就會跳到登入帳號密碼的畫面。簡單的多人登入登出的動作就可運作了。

只有看上述的程式介紹,而沒看到 screenshot ,真的就覺得不夠實在,這兩天剛有新機器上線,再整理一下門面就放上來供參考。

參考資料
http://railscasts.com/episodes/67
http://www.railsforum.com/viewtopic.php?id=14216
http://railsforum.com/viewtopic.php?pid=74245#p74245
http://www.bllll.com/thread-36539-1-1.html


上一篇
[RoR] 用 nginx 作為 RoR 的前端
下一篇
[RoR] 多人用虛擬轉址信箱的建置(1)
系列文
Rails 的簡單任務33

1 則留言

0
gric
iT邦高手 1 級 ‧ 2009-03-13 14:41:50

謝謝分享咯!

我要留言

立即登入留言