本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7578308
建立时间:2006年5月29日




[Ruby on Rails]Login Engine补丁
软件技术

lhwork 发表于 2007/2/8 10:11:29

Login Engine是非常好用的一个登录engine,不过也有个缺点,它把用户信息缓存在session里。如果用户每次修改完自己的资料,都把session更新的话,自然是不会有什么数据不同步的问题。不过试想这样一种情况:1、用户A登录;用户A的信息将保存在session[:user]里。2、管理员操作用户A,修改用户A的资料并保存。3、用户A刷新页面。 如果显示用户资料是从session[:user]读取的话,显然用户A看到的是老的资料。正确的做法是管理员修改用户资料以后,把用户session里的内容也更新,当然这个实施起来有些困难,目前看来无法由用户ID获得对应的session。有朋友说session里不应该缓存用户信息,而应只保存用户ID。这是正确的,这样可以解决上面的问题,不过带来的问题是每次都要从数据库查询。如果每次刷新页面都从数据库重新读取用户信息,对性能影响是很大的。试想一下用户正在浏览一个论坛的帖子列表,这个页面可能所有用户看起来都是一样的,唯一不一样的地方是上面用户信息的显示。由于大部分内容都一样,可以使用缓存加快浏览速度。不过却由于session里只保存了用户ID,不得不读取数据库来获得用户信息,这样就把速度又拖慢了。所以应该把用户信息缓存起来,但要保证它能及时更新。方法自己做一个缓存管理器,能根据用户ID得到用户信息,也能随时更新它。学着ActionController::Caching做了一个UserManager,它可以根据线程配置来自动开关互斥器:(/vender/plugins/login_engine/lib/login_engine/user_management.rb) module UserManagement  # :nodoc:   class UnthreadedUserManager  # :nodoc:     def initialize  # :nodoc:        @users   =  {}    end        def get(user_id)       @users [user_id]    end        def set(user_id ,  user)       @users [user_id]  =  user    end  end    module ThreadSafety  # :nodoc:     def get(user_id)  # :nodoc:        @mutex . synchronize { super }    end    def set(user_id ,  user)  # :nodoc:        @mutex . synchronize { super }    end  end    class UserManager  <  UnthreadedUserManager    def initialize      super       if  ActionController :: Base . allow_concurrency         @mutex   =  Mutex . new        UserManager . send ( : include ,  ThreadSafety)      end    end  end    @ @user_manager   =  UserManagement :: UserManager . new    def set_current_user(user)     return  session[ : user_id]  =  nil  if  user . nil ?     session[ : user_id]  =  user . id    cache_user(user)  end    def current_user    get_user(session[ : user_id])  end    def cache_user(user)     return   if  user . nil ?     @ @user_manager . set(user . id ,  user)  end    def get_user(user_id)    @ @user_manager . get(user_id)  endend   修改(/verdor/plugins/login_engine/lib/login_engine.rb): #500)this.width=500'>500)this.width=500'>.require 'login_engine/user_management'module LoginEngine  include UserManagement  #500)this.width=500'>.end加入上面加粗的2行。修改(/verdor/plugins/login_engine/lib/login_engine/authenticated_system.rb),把session[:user]替换为session[:user_id]。修改(/verdor/plugins/login_engine/app/controllers/user_controller.rb):   def login    return if generate_blank    @user = User.new(params[:user])    if user = User.authenticate(params[:user][:login], params[:user][:password])      user.logged_in_at = Time.now      user.save      set_current_user(user)      flash[:notice] = "Login successful"      redirect_to_stored_or_default :action => 'home'    else      @login = params[:user][:login]      flash.now[:warning] = 'Login unsuccessful'    end  end   def logout    set_current_user(nil)    redirect_to :action => 'login'  end   def get_user_to_act_on    @user = current_user  end简单测试: require 'login_engine'class ApplicationController < ActionController::Base  include LoginEngine    helper :user  model :user      before_filter :login_requiredend class ShowController < ApplicationController  def show    render_text "User name: #{current_user.first_name}"  endend class AdminController < ApplicationController  def edit    user = User.find(params[:id])    user.update_attributes(:first_name => params[:name])    cache_user(user)    render_text "User name: #{user.first_name}"  endend一个简单的模拟:1、用户A从IE登录,访问/show/show,将显示用户的名字。2、管理员从FF登录,访问/show/show,将显示管理员名字。3、管理员访问/show/show/2?name=hello,其中2是用户A的ID。这将把用户A的名字修改为hello。4、用户A刷新页面,可以看到显示的用户名字已经发生变化。以上过程说这个修改已经达到目的。实现这个功能并不难,主要是为了保留Login Engine原有的功能不变。修改后的代码:www.cppblog.com/Files/cpunion/login_engine.rar


阅读全文(2708) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144767015 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号