views:

584

answers:

1

Hi Everyone,

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, :current_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

A: 

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.

Jeff Terrell