我想成为世界级的软件开发者。现在读大学三年级。欢迎发E-mail与我讨论关于软件开发的各种想法。 我的新blog在http://redworld.blog.ubuntu.org.cn/

Rails,用户认证

上一篇 / 下一篇  2008-01-28 17:00:13 / 个人分类:Ruby

查看( 74 ) / 评论( 2 )
最近自己写了写代码,研究了一下关于Rails中用户认证方面的知识。

Rails中的用户认证解决方法,看到大多数是靠插件实现,比如:
LoginGenerator
Acts_as_authenticated
restful_authentication
......

其中采用的方法都类似于《Agile Web 2e》的dopet示例的处理方法:

  • 通过虚拟的password属性来作为密码
  • 通过随机生成的salt和密码明文(或者MD5等方法)加密后存入数据库
  • 在controller中通过before_filter来阻止未通过认证的用户对action进行调用
  • 在view中通过如islogin?,isadmin?等方法来让保护需要登录或者为管理员的行为


插件中一般都是做出一个Model和两个Controller,处理用户数据的User。而Controller,一个负责登录和登出,另一个User的负责用户创建和删除。

关于记住用户状态的实现,大部分用户认证的插件都有。参考User+authentication+in+Ruby+on+Rails
添加一个cookie_hash字段到user中:

CODE:

class AddUserCookieHash < ActiveRecord::Migration
  def self.up
    add_column :users, :cookie_hash, :string
  end

  def self.down
    remove_column :users, :cookie_hash
  end
end
接着在登录页面,如login.html.erb中,加入:

CODE:

<%= check_box_tag :remember %> remember me然后在管理login的controller中添加:

CODE:

def login
    if request.post?
      @user = User.find_by_username(params[:login])
        if @user and @user.password_is? params[:password]
          session[:uid] = @user.id
         
          # 当用户需要被记住时,开始对cookie进行处理
          # 对cookie生成一个密钥之后放入cookie和存入数据库(user表中)
          # 其中还指定了一个cookies失效时间,默认为30天,其实可以把这个参数提出来
          if params[:remember]
            cookie_pass = [Array.new(9){rand(256).chr}.join].pack("m").chomp
            cookie_hash = Digest::MD5.hexdigest(cookie_pass + @user.password_salt)
            cookies[:userapp_login_pass] = { :value => cookie_pass, :expires => 30.days.from_now }
            cookies[:userapp_login] = { :value => @user.username, :expires => 30.days.from_now }
            User.update(@user.id, :cookie_hash => cookie_hash)
          end

          redirect_to :controller => 'panel', :action => 'secret'
        else
           @auth_error = 'Bad username or password'
        end
    end
最后在ApplicationController中加入:

CODE:

  session :session_key => '_userapp_session_id'
  before_filter :check_cookie
  
  def check_cookie
    return if session[:uid]
      if cookies[:logowanie_login]
        @user = User.find_by_username(cookies[:userapp_login])
        return unless @user
        cookie_hash = Digest::MD5.hexdigest(cookies[:userapp_login_pass] + @user.password_salt)
        if @user.cookie_hash == cookie_hash
          flash[:info] = 'You\'ve been automatically logged in' # annoying msg
          session[:uid] = @user.id
        else
          flash[:error] = 'Something is wrong with your cookie'
        end
      end
  end
而关于角色的认证可以使用插件:ActiveRBAC

[ 本帖最后由 maninred 于 2008-1-28 17:02 编辑 ]

TAG:

小飞猪之Ruby窝 drive2me 发布于2008-01-28 21:31:30
实用的说明,越多越好。
lgn21st发布于2008-01-29 01:34:40
精品文章,建议maninred再加上一点userstory和testcase。
我来说两句

(可选)

日历

« 2009-01-08  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 1600
  • 日志数: 63
  • 书签数: 3
  • 建立时间: 2007-10-09
  • 更新时间: 2008-02-15

RSS订阅

Open Toolbar