Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook canvas app not saving Sessions

I made a test facebook app just to play around and I am using sessions to store the authentification. I am using omniauth. When I go to log in from http://fbbtest.heroku.com/ and then refresh the page the session is still saved and it says that I am logged in. When I try it from the canvas http://apps.facebook.com/herokutestapp/ it logs me in, redirects back and says that I am logged in but then when I manually refresh it then says that I am not logged in. Is there something special that I have to do with sessions in rails 3 so that it also works in the facebook canvas?

This what I currently have in my controllers and views

  def index

  end

  def create
    session['fb_auth'] = request.env['omniauth.auth']
    session['fb_token'] = session['fb_auth']['credentials']['token']
    session['fb_error'] = nil
    redirect_to root_path
  end

  def destroy
    clear_session
    redirect_to root_path
  end

  def failure
    clear_session
    session['fb_error'] = 'In order to use this site you must allow us access to your Facebook data<br />'
    redirect_to root_path
  end

  def clear_session
    session['fb_auth'] = nil
    session['fb_token'] = nil
    session['fb_error'] = nil
  end

Index View

<div class="container">
    <h1>Heroku FB Test application</h1><br />
    <div class="center"><br />
<%=session[:fb_error]%>     
    <% if session[:fb_token] %>
      <p>
        Successfully logged in.
      </p>
      <a href='logout'>Logout</a>
    <% else %>
        <%= session[:fb_error] %><br />
            <%= link_to "Log in with Facebook", "/auth/facebook",:class => "popup", :"data-width" => 600, :"data-height" => 400 %> <br />
        <p>
            please log in
        </p>
    <% end %>
    </div>
</div>
like image 397
Kevin Avatar asked Apr 21 '11 04:04

Kevin


2 Answers

The problem you're possibly running into is that Rails CSRF forgery detection is creaming some part of your authentication because the requests are coming in as HTTP Method POST.

The first line in your ApplicationController is probably something like:

class ApplicationController < ActionController::Base
  protect_from_forgery
  [...]

Remove that 'protect_from_forgery' line and see if that helps with your problem. If that turns out to be the case, go back and set that up on a more limited basis (just the relevant controllers, see documentation here: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html )

There's an great example for getting Omniauth working at http://www.communityguides.eu/articles/16, and the full sample code is at https://github.com/markusproske/omniauth_pure. On that, they have the following:

class ServicesController < ApplicationController
  before_filter :authenticate_user!, :except => [:create, :signin, :signup, :newaccount, :failure]
  protect_from_forgery :except => :create     

You need some variant of both those lines to make omniauth, facebook, and rails sessions play well together. If that doesn't work out for you, post your OmniAuth::Builder information from environment/production.rb (with details XXXed out) and any other related code in the controller you use for authentication, that will be helpful for debugging this.

It may be easier when developing rails apps using facebook to debug using http://tunnlr.com or another service (or just an ssh tunnel http://blog.kenweiner.com/2007/09/reverse-ssh-tunnel-for-facebook.html) that lets you run the debugger on your local machine, it is very helpful for figuring these sorts of problems out.

like image 101
corprew Avatar answered Nov 09 '22 01:11

corprew


Sessions and cookies in Facebook iframes are very difficult to use, but not impossible. I've faced this a few times when trying to develop vote-once-per-day contests.

The solution is to use P3P headers. Honestly I'm not too sure how they work, but it reduces issues of cross-browser cookies in iframes - especially IE and Safari.

Add the following to the top of each page:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

This may not solve your issue exactly but hopefully it can help get you on the right path.

like image 34
Carson Avatar answered Nov 09 '22 03:11

Carson