Skip to main content
The Kai Way

Rails的用户认证

最近自己写了写代码,研究了一下关于Rails中用户认证方面的知识。

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

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

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

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

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中,加入:

remember me

然后在管理login的controller中添加:

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 end

最后在ApplicationController中加入:

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