authenticate是一个非常有用,也使用非常普遍的插件,在制作memU的时候舍弃了自己造轮子的想法,转而使用这个插件,插件代码不难,但是通过阅读,仍然有很大的收获,下面简单分析一下authentic的源码
从Login说起
首先从登录场景开始分析
从代码来看,使用get方式调用此action会直接渲染login.rhtml,此rhtml中form仍然提交给login,此时form中的用户名和email字段被包装成params[:login],params[:password],此时,首先调用User对象模型的authenticate方法,此方法实际上调用了User.find_by_login方法,假如用户不存在或者密码不匹配,会返回nil。self.current_user实际上调用了authenticated_system.rb中的current_user=()方法,让我们看看相关两个方法的源代码:
如果new_user为nil的话,session[:user]会被设置为:false,否则会保存用户的id,同时,把实例变量@current_user设置为new_user的值。接下来的logged_in?判断session[:user]是否不为:false,是则登录成功,否则重新render当前视图模板。在logged_in?为true之后,会判断用户是否选择了remember_me,如果选择了,则调用current_user方法得到模型对象@current,再调用实例方法remember_me,可以看到,插件没有提供选择cookie保存时间的选项,我们需要自己加上,而插件本身默认的保存时间是两个星期:
之后,跳转,我们这里需要改变下面一个方法的参数,这个参数同redirect_to方法的参数格式一致(实际上它内部调用了redirect_to方法)
从Login说起
首先从登录场景开始分析
ruby 代码
- def login
- return unless request.post?
- self.current_user = User.authenticate(params[:login], params[:password])
- if logged_in?
- if params[:remember_me] == "1"
- self.current_user.remember_me
- cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
- end
- redirect_back_or_default(:controller => '/account', :action => 'index')
- flash[:notice] = "Logged in successfully"
- end
- end
ruby 代码
- def current_user
- @current_user ||= (session[:user] && User.find_by_id(session[:user])) || :false
- end
- # Store the given user in the session.
- def current_user=(new_user)
- session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
- @current_user = new_user
- end
ruby 代码
- def remember_me
- self.remember_token_expires_at = 2.weeks.from_now.utc
- self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
- save(false)
- end
ruby 代码
- redirect_back_or_default(:controller => '/account', :action => 'index')