Coder Social home page Coder Social logo

kalendae / pinkydata Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 0.0 204 KB

select a facebook friend to see what likes you have in common. heroku based skeleton facebook iframe canvas app using koala. persists no tokens etc, so will fail first if facebook deprecates anything the app relies on (canary in the mine)

Home Page: http://pinkydata.heroku.com

Ruby 80.25% JavaScript 19.75%

pinkydata's Introduction

Need to have signed_request migration turned on in the advanced setting of the app on 
facebook.


Flow:

  1) If there is a signed_request but it does not contain oauth_token or user_id:
     new user or not signed in user, redirect to oauth sign_in

  2) If there is a signed_request and oauth_token and user_id exist:
     an authorized user signing in, create session[:user] and store token

  3) there is no signed_request, and no session[:user]
     unknown or timed out, redirect to oauth sign_in

  4)there is no signed_request, but session[:user] exist
     a current user in the app, do nothing


Top redirect:

  it is necessary to cause the entire window (not just the iframe) to redirect
  when the app needs to redirect to things like the facebook oauth login url.

  def top_redirect_to(*args)
    @redirect_url = url_for(*args)
    render :layout => false, :inline => <<-HTML
      <html><head>
        <script type="text/javascript">
          window.top.location.href = "<%= @redirect_url %>".replace(/&amp;/gi,"&");
        </script>
        <noscript>
          <meta http-equiv="refresh" content="0;url=<%=h @redirect_url %>" />
          <meta http-equiv="window-target" content="_top" />
        </noscript>
      </head></html>
    HTML
  end


Safari cookie fix for rails session to work inside facebook iframe (any cross domain 
iframe):

taken from:
http://saizai.livejournal.com/897522.html?thread=2771442

Using cookies in an external iframe with Safari - aka, getting Rails sessions in a Facebook 
iframe

The problem:

1. Safari does not allow an iframe with a domain different from the domain of the main page 
to set cookies unless the user 'actively' navigates it, i.e. clicks a link.

2. Facebook apps using iframes are an instance of this - the main page is apps.facebook.com, 
and the iframe is some.developer.site.


The solution:

(Note: I use MainController for storing most static pages and the very rare random-shit 
page, like this. YMMV.)

1. app/controllers/application.rb

Somewhere that will get executed whenever a user loads the page normally (e.g. a universal 
before_filter), do:

cookies['safari_cookie_fix'] = 'cookie OK'


This will signal to the page that the cookie has been set successfully.

2. app/controllers/main_controller.rb

  session :off, :only => :set_cookie

  def set_cookie
    cookies['safari_cookie_fix'] = params[:_session_id]
    redirect_to params[:redirect_to] and return
  end


This will get automatically posted to if the cookie did NOT get loaded (i.e. we're in the 
first page of a Safari iframe and Safari dropped our cookie in the trash).

session :off is because it doesn't yet have any cookie to get its session info from.

This action will basically just redirect onwards to the place you were supposed to be in the 
first place. The fact of redirecting will mean that Safari now thinks it's OK to set the 
cookie, and therefore, Rails' automagic session cookie setters will work too.

Actually setting the cookie is AFAICT superfluous but helpful for debugging.


3. config/routes.rb

map.safari_cookie_fix "safari_cookie_fix", :controller => 'main', :action => 'set_cookie'


Convenience.


4. app/views/layout.html.erb

Somewhere in your body (preferably high up, so it gets evaluated first and doesn't wait for 
rendering that will get preempted anyway), insert:

<script>
	function safariFixSession(sess_id, controller) {
		alert('no cookie found');
		var url = location.href;
		var url_with_redirect = controller + "?redirect_to=" + url;
		
		$$('body')[0].insert("<form id='safariFixSession'></form>");
		var f = $('safariFixSession')
		f.method = 'POST';
		f.action = url_with_redirect;
		var m = document.createElement('input');
		m.setAttribute('type', 'hidden');
		m.setAttribute('name', '_session_id');
		m.setAttribute('value', sess_id);
		f.appendChild(m);
		f.submit();
	} 

	if (document.cookie.indexOf("safari_cookie_fix") == -1) safariFixSession("<%= 
session[:session_id] %>", "safari_cookie_fix");
</script>


This will add a form to your page with the current session ID (if any) and automatically 
submit it to the controller we made in step 2.

Remember to remove the alert() line! It's very useful for testing but not so great for 
users. ;-)

Note that as I said above, the session ID passing seems to be completely unnecessary, so 
feel free to yank it. What is necessary is simply the auto-form-submit.

It's quite possible that Safari may consider this method a security problem and patch it. If 
so, I'll update this post w/ info if I have any. But Safari people: please make sure that 
app developers who are doing legitimate stuff aren't hurt - it just means that we'll have to 
redirect people to Firefox, hint hint.

     
     

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.