Module: Facebooker2::Rails::Controller
- Defined in:
- lib/facebooker2/rails/controller.rb
Class Method Summary collapse
Instance Method Summary collapse
- #base64_url_decode(encoded) ⇒ Object
- #current_facebook_client ⇒ Object
- #current_facebook_user ⇒ Object
- #facebook_params ⇒ Object
- #fb_cookie ⇒ Object
- #fb_cookie? ⇒ Boolean
- #fb_cookie_hash ⇒ Object
- #fb_cookie_name ⇒ Object
-
#fb_cookie_signature_correct?(hash, secret) ⇒ Boolean
check if the expected signature matches the one from facebook.
- #fb_create_user_and_client(token, expires, userid) ⇒ Object
- #fb_load_facebook_params ⇒ Object
- #fb_sign_in_user_and_client(user, client) ⇒ Object
- #fb_signed_request_json(encoded) ⇒ Object
- #fb_signed_request_sig_valid?(sig, encoded) ⇒ Boolean
-
#fetch_client_and_user ⇒ Object
This mimics the getSession logic from the php facebook SDK github.com/facebook/php-sdk/blob/master/src/facebook.php#L333.
- #fetch_client_and_user_from_cookie ⇒ Object
- #fetch_client_and_user_from_signed_request ⇒ Object
-
#generate_signature(hash, secret) ⇒ Object
compute the md5 sig based on access_token,expires,uid, and the app secret.
-
#oauth2_current_facebook_user ⇒ Object
Oauth2.
- #oauth2_fetch_client_and_user ⇒ Object
- #oauth2_fetch_client_and_user_from_cookie ⇒ Object
-
#set_fb_cookie(access_token, expires, uid, sig) ⇒ Object
/** This method was shamelessly stolen from the php facebook SDK: github.com/facebook/php-sdk/blob/master/src/facebook.php Set a JS Cookie based on the _passed in_ session.
-
#set_p3p_header_for_third_party_cookies ⇒ Object
For canvas apps, You need to set the p3p header in order to get IE 6/7 to accept the third-party cookie For details www.softwareprojects.com/resources/programming/t-how-to-get-internet-explorer-to-use-cookies-inside-1612.html.
-
#signed_request_from_logged_out_user? ⇒ Boolean
If the signed request is valid but contains no oauth token, the user is either logged out from Facebook or has not authorized the app.
Class Method Details
.included(controller) ⇒ Object
7 8 9 10 11 12 |
# File 'lib/facebooker2/rails/controller.rb', line 7 def self.included(controller) controller.helper Facebooker2::Rails::Helpers controller.helper_method :current_facebook_user controller.helper_method :current_facebook_client controller.helper_method :facebook_params end |
Instance Method Details
#base64_url_decode(encoded) ⇒ Object
237 238 239 240 241 |
# File 'lib/facebooker2/rails/controller.rb', line 237 def base64_url_decode(encoded) chars_to_add = 4-(encoded.size % 4) encoded += ("=" * chars_to_add) Base64.decode64(encoded.tr("-_", "+/")) end |
#current_facebook_client ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/facebooker2/rails/controller.rb', line 23 def current_facebook_client if (Facebooker2.oauth2) oauth2_fetch_client_and_user else fetch_client_and_user end @_current_facebook_client end |
#current_facebook_user ⇒ Object
14 15 16 17 18 19 20 21 |
# File 'lib/facebooker2/rails/controller.rb', line 14 def current_facebook_user if (Facebooker2.oauth2) oauth2_fetch_client_and_user else fetch_client_and_user end @_current_facebook_user end |
#facebook_params ⇒ Object
127 128 129 |
# File 'lib/facebooker2/rails/controller.rb', line 127 def facebook_params @facebook_param ||= fb_load_facebook_params end |
#fb_cookie ⇒ Object
90 91 92 |
# File 'lib/facebooker2/rails/controller.rb', line 90 def [] end |
#fb_cookie? ⇒ Boolean
86 87 88 |
# File 'lib/facebooker2/rails/controller.rb', line 86 def !.blank? end |
#fb_cookie_hash ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/facebooker2/rails/controller.rb', line 75 def return nil unless hash={} data = .gsub(/"/,"") data.split("&").each do |str| parts = str.split("=") hash[parts.first] = parts.last end hash end |
#fb_cookie_name ⇒ Object
94 95 96 |
# File 'lib/facebooker2/rails/controller.rb', line 94 def return "#{Facebooker2. + Facebooker2.app_id.to_s}" end |
#fb_cookie_signature_correct?(hash, secret) ⇒ Boolean
check if the expected signature matches the one from facebook
99 100 101 |
# File 'lib/facebooker2/rails/controller.rb', line 99 def (hash,secret) generate_signature(hash,secret) == hash["sig"] end |
#fb_create_user_and_client(token, expires, userid) ⇒ Object
62 63 64 65 66 |
# File 'lib/facebooker2/rails/controller.rb', line 62 def fb_create_user_and_client(token,expires,userid) client = Mogli::Client.new(token,expires.to_i) user = Mogli::User.new(:id=>userid) fb_sign_in_user_and_client(user,client) end |
#fb_load_facebook_params ⇒ Object
131 132 133 134 135 136 |
# File 'lib/facebooker2/rails/controller.rb', line 131 def fb_load_facebook_params return {} if params[:signed_request].blank? sig,encoded_json = params[:signed_request].split(".") return {} unless fb_signed_request_sig_valid?(sig,encoded_json) ActiveSupport::JSON.decode(fb_signed_request_json(encoded_json)).with_indifferent_access end |
#fb_sign_in_user_and_client(user, client) ⇒ Object
68 69 70 71 72 73 |
# File 'lib/facebooker2/rails/controller.rb', line 68 def fb_sign_in_user_and_client(user,client) user.client = client @_current_facebook_user = user @_current_facebook_client = client @_fb_user_fetched = true end |
#fb_signed_request_json(encoded) ⇒ Object
121 122 123 124 125 |
# File 'lib/facebooker2/rails/controller.rb', line 121 def fb_signed_request_json(encoded) chars_to_add = 4-(encoded.size % 4) encoded += ("=" * chars_to_add) base64_url_decode(encoded) end |
#fb_signed_request_sig_valid?(sig, encoded) ⇒ Boolean
138 139 140 141 142 143 |
# File 'lib/facebooker2/rails/controller.rb', line 138 def fb_signed_request_sig_valid?(sig,encoded) base64 = Base64.encode64(HMAC::SHA256.digest(Facebooker2.secret,encoded)) #now make the url changes that facebook makes url_escaped_base64 = base64.gsub(/=*\n?$/,"").tr("+/","-_") sig == url_escaped_base64 end |
#fetch_client_and_user ⇒ Object
This mimics the getSession logic from the php facebook SDK github.com/facebook/php-sdk/blob/master/src/facebook.php#L333
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/facebooker2/rails/controller.rb', line 35 def fetch_client_and_user return if @_fb_user_fetched # Try to authenticate from the signed request first sig = fetch_client_and_user_from_signed_request sig = if @_current_facebook_client.nil? and !signed_request_from_logged_out_user? #write the authentication params to a new cookie if !@_current_facebook_client.nil? #we may have generated the signature based on the params in @facebook_params, and the expiration here is different (@_current_facebook_client.access_token, @_current_facebook_client.expiration, @_current_facebook_user.id, sig) else # if we do not have a client, delete the cookie (nil,nil,nil,nil) end @_fb_user_fetched = true end |
#fetch_client_and_user_from_cookie ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/facebooker2/rails/controller.rb', line 54 def if (hash_data = ) and (,Facebooker2.secret) fb_create_user_and_client(hash_data["access_token"],hash_data["expires"],hash_data["uid"]) return ["sig"] end end |
#fetch_client_and_user_from_signed_request ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/facebooker2/rails/controller.rb', line 145 def fetch_client_and_user_from_signed_request if facebook_params[:oauth_token] fb_create_user_and_client(facebook_params[:oauth_token],facebook_params[:expires],facebook_params[:user_id]) if @_current_facebook_client #compute a signature so we can store it in the cookie sig_hash = Hash["uid"=>facebook_params[:user_id],"access_token"=>facebook_params[:oauth_token],"expires"=>facebook_params[:expires]] return generate_signature(sig_hash, Facebooker2.secret) end end end |
#generate_signature(hash, secret) ⇒ Object
compute the md5 sig based on access_token,expires,uid, and the app secret
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/facebooker2/rails/controller.rb', line 110 def generate_signature(hash,secret) sorted_keys = hash.keys.reject {|k| k=="sig"}.sort test_string = "" sorted_keys.each do |key| test_string += "#{key}=#{hash[key]}" end test_string += secret sig = Digest::MD5.hexdigest(test_string) return sig end |
#oauth2_current_facebook_user ⇒ Object
Oauth2
214 215 216 217 |
# File 'lib/facebooker2/rails/controller.rb', line 214 def oauth2_current_facebook_user oauth2_fetch_client_and_user @_current_facebook_user end |
#oauth2_fetch_client_and_user ⇒ Object
219 220 221 222 223 |
# File 'lib/facebooker2/rails/controller.rb', line 219 def oauth2_fetch_client_and_user return if @_fb_user_fetched sig = if @_current_facebook_client.nil? @_fb_user_fetched = true end |
#oauth2_fetch_client_and_user_from_cookie ⇒ Object
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/facebooker2/rails/controller.rb', line 225 def return unless sig,payload = .split('.') return unless fb_signed_request_sig_valid?(sig, payload) data = JSON.parse(base64_url_decode(payload)) authenticator = Mogli::Authenticator.new(Facebooker2.app_id, Facebooker2.secret, '') client = Mogli::Client.create_from_code_and_authenticator(data["code"], authenticator) user = Mogli::User.new(:id=>data["user_id"]) fb_sign_in_user_and_client(user, client) end |
#set_fb_cookie(access_token, expires, uid, sig) ⇒ Object
/**
This method was shamelessly stolen from the php facebook SDK:
https://github.com/facebook/php-sdk/blob/master/src/facebook.php
Set a JS Cookie based on the _passed in_ session. It does not use the
currently stored session -- you need to explicitly pass it in.
If a nil access_token is passed in this method will actually delete the fbs_ cookie
*/
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/facebooker2/rails/controller.rb', line 168 def (access_token,expires,uid,sig) #default values for the cookie value = 'deleted' expires = Time.now.utc - 3600 unless expires != nil # If the expires value is set to some large value in the future, then the 'offline access' permission has been # granted. In the Facebook JS SDK, this causes a value of 0 to be set for the expires parameter. This value # needs to be correct otherwise the request signing fails, so if the expires parameter retrieved from the graph # api is more than a year in the future, then we set expires to 0 to match the JS SDK. expires = 0 if expires > Time.now + 1.year if access_token # Retrieve the existing cookie data data = || {} # Remove the deleted value if this has previously been set, as we don't want to include it as part of the # request signing parameters data.delete('deleted') if data.key?('deleted') # Keep existing cookie data that could have been set by FB JS SDK data.merge!('access_token' => access_token, 'uid' => uid, 'sig' => sig, 'expires' => expires.to_i.to_s) # Create string to store in cookie value = '"' data.each do |k,v| value += "#{k.to_s}=#{v.to_s}&" end value.chop! value+='"' end # if an existing cookie is not set, we dont need to delete it if (value == 'deleted' && (! || == "" )) return; end #My browser doesn't seem to save the cookie if I set expires [] = { :value=>value }#, :expires=>expires} end |
#set_p3p_header_for_third_party_cookies ⇒ Object
For canvas apps, You need to set the p3p header in order to get IE 6/7 to accept the third-party cookie For details www.softwareprojects.com/resources/programming/t-how-to-get-internet-explorer-to-use-cookies-inside-1612.html
209 210 211 |
# File 'lib/facebooker2/rails/controller.rb', line 209 def response.headers['P3P'] = 'CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"' end |
#signed_request_from_logged_out_user? ⇒ Boolean
If the signed request is valid but contains no oauth token, the user is either logged out from Facebook or has not authorized the app
105 106 107 |
# File 'lib/facebooker2/rails/controller.rb', line 105 def signed_request_from_logged_out_user? !facebook_params.empty? && facebook_params[:oauth_token].nil? end |