I'm currently building a web application in Rails. I'm using Authlogic to handle normal authentication. I'm using facebooker to handle facebook connect on the external site and to authenticate users within the facebook canvas application.
I'm having trouble building simple, coherent current_user functionality. Currently I have a whole mess of different methods getting/setting the current user, and I'd like to simplify this as much as possible.
I'm using active_record_store for my sessions (defined in environment.rb) Here is my application Controller:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
filter_parameter_logging :fb_sig_friends, :password, :password_confirmation
helper_method :facebook_session, :current_user_session, :cu开发者_运维问答rrent_user
before_filter :fb_setup
attr_accessor :current_user
helper_attr :current_user
#Before filter to decide if we should use facebook sessions to set current user
def fb_setup
if request_comes_from_facebook?
ensure_authenticated_to_facebook
set_current_fb_user
end
end
############
# AuthLogic
############
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.user
end
##########
# Facebook
##########
def create_user
self.current_user = User.for(facebook_session.user.to_i, facebook_session)
end
def set_current_fb_user
self.current_user = User.for(facebook_session.user.to_i, facebook_session)
end
end
And in my User model, I have these methods to help finding/creating a user from a facebook id: def self.for(facebook_id,facebook_session=nil) returning find_or_create_by_facebook_id(facebook_id) do |user| unless facebook_session.nil? user.store_session(facebook_session.session_key) end end end
def store_session(session_key)
if self.session_key != session_key
update_attribute(:session_key,session_key)
end
end
def facebook_session
@facebook_session ||=
returning Facebooker::Session.create do |session|
session.secure_with!(session_key,facebook_id,1.day.from_now)
end
end
What confuses this, is that authlogic's methods only get called when the current_user is required, but facebook's set_current_fb_user is called before every request.
I need either self.current_user or @current_user set in application_controller in a coherent way regardless of which session is responsible for setting the current_user. I'm having trouble doing this and the rest of my code base is suffering because of this. If anyone has any advice, it would be much appreciated.
If you need any additional info, I'll be happy to provide it.
Thanks
The set_current_fb_user
method is called upon every request because it is called from fb_setup
, which is a before_filter
of ApplicationController
(and all controllers inherit from ApplicationController
). However, you don't have any before_filter
method that always calls current_user
. So, try changing the before_filter
line to:
before_filter [:set_current_fb_user, :current_user]
Note that if set_current_fb_user
returns a false value, then current_user
won't be called.
See the Rails Action Controller Guide for more information.
精彩评论