Created
October 25, 2010 06:13
-
-
Save aaronvb/644482 to your computer and use it in GitHub Desktop.
This will allow you to verify and parse the Facebook Javascript Connect cookie for Ruby/Ruby on Rails. Currently working this into a gem: http://github.com/aaronvb/fb_js_connect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'digest/md5' | |
class FbJsConnect | |
# When using the Facebook Javascript SDK to connect users to your site, | |
# a cookie will be placed in your applications session store. This class | |
# will verify your cookie, tell you if you're connected, and provide | |
# you with a User and other information | |
# | |
# cookie = cookies["fbs_YOUR FACEBOOK APP ID"] | |
# fb = FbJsConnect.new(cookie) | |
# fb.connected => true or false | |
# fb.verified? => true or false | |
# fb.user => User or nil (Assuming you have a User class with the | |
# attribute fb_uid) | |
# fb.uid if fb.connected => uid if connected | |
# fb.access_token if fb.connected => access_token if connected | |
# Verification works by combining cookie key + values, minus sig, | |
# appending app_secret, then MD5 hashing it. | |
# The value of the MD5 should equal the sig value. | |
attr_accessor :connected | |
def initialize(cookie) | |
@app_id = "" # YOUR FACEBOOK APP ID | |
@app_secret = "" # YOUR FACEBOOK APP SECRET KEY | |
fb_cookie = cookie | |
if fb_cookie | |
# remove any quotes in cookie. Facebook puts it's cookie in | |
# quotes for some reason | |
fb_cookie.gsub!('"','') | |
# split cookie values into array by '&' symbol | |
fb_cookie = fb_cookie.split("&") | |
fb_cookie_hash = Hash.new | |
fb_cookie.each do |c, i| | |
key_value_arr = c.split("=") # split value into kv hash | |
fb_cookie_hash[key_value_arr[0]] = key_value_arr[1] # add to new hash | |
end | |
@fb_cookie_hash = fb_cookie_hash # for verification | |
# apply connected and fb_cookie_hash to class attributes IF verified | |
if self.verified? | |
@attributes = fb_cookie_hash | |
self.connected = true | |
end | |
else | |
# no cookie found so return false | |
self.connected = false | |
end | |
end | |
def verified? | |
Rails.logger.debug("\nFB: digested sig: #{process}") | |
Rails.logger.debug("FB: sig: #{@sig}\n\n") | |
if process == @sig | |
return true | |
else | |
return false | |
end | |
end | |
def user | |
# find user with UID | |
# | |
user = User.find(:first, :conditions => {:fb_uid => | |
@fb_cookie_hash["uid"]}) | |
if user | |
return user # a user was found with UID | |
else | |
return nil # a user was not found | |
end | |
end | |
def method_missing(name, *args) | |
attribute = name.to_s | |
if attribute =~ /=$/ | |
@attributes[attribute.chop] = args[0] | |
else | |
@attributes[attribute] | |
end | |
end | |
private | |
def process | |
@sig = @fb_cookie_hash['sig'] # get sig to compare final hash | |
payload = [] | |
@fb_cookie_hash.each do |k, v| | |
payload.push "#{k}=#{v}" unless k == "sig" | |
end | |
digest = Digest::MD5.hexdigest(payload.sort.to_s + @app_secret) | |
return digest | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment