Ruby on Rails 建立用戶系統及加入OpenID

Ruby on Rails 建立用戶系統及加入OpenID

每個Web Application 也為了建立一個安全方便的用戶系統或登入系統而遇上麻煩。Don't Repeat Yourself (DRY), 我們可使用RoR的Plugins解決煩惱!

說到用戶系統,不能不提 MySpacefacebook 等公司也非常投入的OpenID 。在RoR 使用OpenId 是非常簡單的事。

Step 1: Signup 登記使用者

先安裝 acts_as_authenticated plugins, 它負責所有基本登入工作。在console 跳至<application_root>

ruby script/plugin install 
http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated/

 

 

安裝後可以用 acts_as_authenticated 建立 "user " Model 和 "account " Controller.

script/generate authenticated user account

這樣便建立了相關的Model 和 Controller。現在設定 Database 。

rake db:migrate  

Database 設定完畢,讀者可以檢查使用的 Database 是否有一個新的 Table "users "。所有用戶資料將會放在這裡。

令人喜出望外的是,你已經擁有基本用戶系統的所有編碼,測試時間到了!

ruby script/server

ror_01

打開 "/account/signup" ,可看到 Signup頁面

打開 /account/signup ,可看到Signup頁面。測試建立一個使用者後,看看資料庫是否更新,完成第一步。

 

Step 2: 設定登入保護  

我們演示登入保護,只要在 Views 和 Controllers 做一點修改便可。

首先,在<application root>/app/views/account 新增 "show.rhtml ",貼上以下編碼。

<%=link_to "log out", "/account/logout"%>

<p><%=current_user.login %> is logged in.</p>

因為acts_as_authenticated 已把基本設定寫妥,我們打開<application root>/app/controllers/account_controller.rb ",在 "include AuthenticatedSystem "下一行插入:

  before_filter :login_required, :except => [:login, :signup]

before_filter 設定先決的 action ,這裡我們執行 acts_as_authenticatedlogin_required action。所以這 controller 的所有 actions 也有預設登入保護。

因為我們加入了 :except => [:login, :signup] ,那麼 loginsignup 兩個頁面也不會被登入保護,沒有用戶的人仕也可瀏覽這兩個頁面。

測試!在瀏覽器鍵入 http://localhost:3000/account/show

ror_02

show 被登入保護了

Ooops,被送到 "login " 頁面。因為"show " 被登入保護了。這時候可以登入剛才新增的使用者:

ror_03

登入後被送到 show

成功登入後便會自動送到"show "。

現在你的application 已有一個完整的登入系統了!

**如果你的 "account_controller.rb" 有其他 actions ,或者 "/views/account" 有其他頁面,也會有登入保護的了。

 

 

Step 3: OpenID

終於到精采部份了,就是為加入OpenID! 如果你不使用OpenID ,可以跳過這部份。但這樣做之前要留意,OpenID 是一個十分成功的共用登入系統,MySpacefacebook 也參與其中。以下是OpenId 編碼

安裝 ruby-openid RubyGems

sudo gem install ruby-openid -y

安裝 restful_authentication

script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication

安裝 open_id_authentication

這個 Plugins 和Rails 2.x 的相容問題較多。筆者發現一個較好的版本,不過它放在 github 裡。要先到 http://github.com/rails/open_id_authentication/tree/master  下載。解壓後改名為open_id_authentication 文件夾,並把它移到<application root>/vendor/plugins 內。

ror_04

現在共有三個Plugins: acts_as_authenticated, restful_authentication, open_id_authentication

建立新 Tables

open_id_authentication 要兩個Database Tables 來記錄OpenId 資料,執行以下指令來建立。

rake open_id_authentication:db:create

rake db:migrate

open <application root>/config/routes.rb ; 確保以下編碼正在運作。

map.root :controller => 'account'

 

Views 修改

先修改"<application root>/app/views/account/login.rhtml " ,在 "<p><%= submit_tag 'Log in' %></p>" 上面插入:

<p> use OpenID ... </p>
<p> <%= text_field_tag "openid_url" %> </p>

再把"<application root>/app/views/account/show.rhtml" 改寫成:

<%=link_to "log out", "/account/logout"%>
<% if current_user.not_openid?%>
<p><%=current_user.login %> is logged in.</p>

<% else %>
<p><%=current_user.identity_url %> is logged in as an open id user.</p>
<% end %>

Models修改

Model 只有一個相關的 <application root>/app/models/user.rb 。但這 user.rb 檔案有幾處要修改。

1. 加入 def not_openid?

  def not_openid?
    identity_url.blank?
  end

2. 修改def password_required?

  def password_required?
    not_openid? && (crypted_password.blank? or not password.blank?)
  end

3. 加入":if => :not_openid?"  至幾個validations,讓openid 使用者避開該項核對。


validates_presence_of     :login, :email, :if => :not_openid?
validates_length_of       :login,    :within => 3..40, :if => :not_openid?
validates_length_of       :email,    :within => 3..100, :if => :not_openid?


Controllers 修改:

只須修改"<application root>/app/controllers/account_controller.rb" 。這檔案也要修改幾處地方。

1. 修改 login ,以加入OpenId 登入:

def login
    return unless request.post?
    if using_open_id?
      open_id_authentication(params[:openid_url])
    elsif params[:login]
      password_authentication(params[:login], params[:password])
    end
  end

3. 修改password_authentication (如有需要的話)

   def password_authentication(login, password)
      if self.current_user = User.authenticate(params[:login], params[:password])
        successful_login
      else
        failed_login("Invalid login or password")
      end
    end

4. 加入 open_id_authentication

    def open_id_authentication(openid_url)
      authenticate_with_open_id openid_url, :required => [:nickname, :email] do |result, identity_url, registration|
        if result.successful?
          @user = self.current_user = User.find_or_create_by_identity_url(identity_url)
          if @user.new_record?
            # registration is a hash containing the valid sreg keys given above
            # use this to map them to fields of your user model
            {'login=' => 'nickname', 'email=' => 'email'}.each do |attr, reg|
              current_user.send(attr, registration[reg]) unless registration[reg].blank?
            end
            if @user.valid?
              @user.save
              self.current_user = @user
              successful_login
            else
              failed_login "Authentication failed on this website."
            end
          else
            self.current_user = @user
            successful_login
          end
        else
          failed_login result.message
        end
      end
    end

這個 action 精明地完成OpenId 核對,並把一些項目從OpenId Server 取回(假設你的OpenId 戶口有:nickname:email 這兩項資料) 。如果是application 的新用者,這些變數將自動用作建立新用者的設定,即是一個新用者也完全不須使用signup 頁面。

5. 加入兩個跳頁用的action

private
    def successful_login
      redirect_back_or_default({:action => :show})
      flash[:notice] = "Logged in successfully"
    end

    def failed_login(message)
      redirect_to(:action => 'login')
      flash[:warning] = message
    end

6. 設定 Database 。

打開console ,跳到在 <application root>

ruby script/generate migration AlterUserIdentityUrl

打開<application root>/db/migration/<新的編號_alter_user_identity_url.rb> ,改寫為:

class AlterUserIdentityUrl < ActiveRecord::Migration
def self.up
  add_column :users, :identity_url, :string
  end

  def self.down
  remove_column :users, :identity_url
  end
end

rake db:migrate  

完成!可以測試了。 當然,讀者要先登記一個OpenId (詳情請參閱 http://openid.net/  )

http://localhost:3000/account/login  ,我用一個沒有在localhost登記的OpenId

ror_05

先輸入你的Open Id ,然後按Submit

登入後,會自動跳到OpenId Server,這時要登入OpenId 一次。

ror_06

你會被送到OpenId Server,輸入你的OpenId password ,並按登入

成功後,你便會使用OpenId 登入localhost ,並跳至相關頁面。

ror_07

 用OpenId 跳至show頁面

總結

在建立一個使用者系統,acts_as_authenticated Plugins 帶給我們很大的方便。"script/generate authenticated user account " 已經把大部份編碼完成。

之後我們使用ruby-openid gem 和 open_id_authentication ,它們使存取OpenId 極之方便。甚至新的使用者也可直接登入系統!只要在 OpenId 登入一次後,那麼以後到任何一個你信任的 OpenId 網站也不用再次登入或登記了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值