Module: Facebooker2::Rails::Controller
- Defined in:
- lib/facebooker2/rails/controller.rb
Class Method Summary collapse
Instance Method Summary collapse
- #base64_url_decode(encoded) ⇒ Object
- #clear_fb_cookie ⇒ 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_logout! ⇒ 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_fetch_client_and_user ⇒ Object
Oauth2.
- #oauth2_fetch_client_and_user_from_cookie ⇒ Object
- #oauth2_fetch_client_and_user_from_session ⇒ Object
- #oauth2_store_client_and_user_in_session(client, user) ⇒ 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
259 260 261 262 263 |
# File 'lib/facebooker2/rails/controller.rb', line 259 def base64_url_decode(encoded) chars_to_add = 4-(encoded.size % 4) encoded += ("=" * chars_to_add) Base64.decode64(encoded.tr("-_", "+/")) end |
#clear_fb_cookie ⇒ Object
94 95 96 |
# File 'lib/facebooker2/rails/controller.rb', line 94 def .delete 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
131 132 133 |
# File 'lib/facebooker2/rails/controller.rb', line 131 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
98 99 100 |
# File 'lib/facebooker2/rails/controller.rb', line 98 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
103 104 105 |
# File 'lib/facebooker2/rails/controller.rb', line 103 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
135 136 137 138 139 140 |
# File 'lib/facebooker2/rails/controller.rb', line 135 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_logout! ⇒ Object
251 252 253 254 255 256 |
# File 'lib/facebooker2/rails/controller.rb', line 251 def fb_logout! session[:facebooker2_access_token]=nil session[:facebooker2_expiration]=nil session[:facebooker2_user_id]=nil 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
125 126 127 128 129 |
# File 'lib/facebooker2/rails/controller.rb', line 125 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
142 143 144 145 146 147 |
# File 'lib/facebooker2/rails/controller.rb', line 142 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
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/facebooker2/rails/controller.rb', line 149 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
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/facebooker2/rails/controller.rb', line 114 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_fetch_client_and_user ⇒ Object
Oauth2
219 220 221 222 223 |
# File 'lib/facebooker2/rails/controller.rb', line 219 def oauth2_fetch_client_and_user return if @_fb_user_fetched oauth2_fetch_client_and_user_from_session || @_fb_user_fetched = true end |
#oauth2_fetch_client_and_user_from_cookie ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 |
# 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"]) oauth2_store_client_and_user_in_session(client,user) fb_sign_in_user_and_client(user, client) end |
#oauth2_fetch_client_and_user_from_session ⇒ Object
243 244 245 246 247 248 249 |
# File 'lib/facebooker2/rails/controller.rb', line 243 def oauth2_fetch_client_and_user_from_session if session[:facebooker2_access_token] client = Mogli::Client.new(session[:facebooker2_access_token],session[:facebooker2_expiration]) user = Mogli::User.new(:id=>session[:facebooker2_user_id]) fb_sign_in_user_and_client(user, client) end end |
#oauth2_store_client_and_user_in_session(client, user) ⇒ Object
237 238 239 240 241 |
# File 'lib/facebooker2/rails/controller.rb', line 237 def oauth2_store_client_and_user_in_session(client, user) session[:facebooker2_access_token] = client.access_token session[:facebooker2_expiration] = client.expiration session[:facebooker2_user_id] = user.id 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
*/
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 205 206 207 208 |
# File 'lib/facebooker2/rails/controller.rb', line 172 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
213 214 215 |
# File 'lib/facebooker2/rails/controller.rb', line 213 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
109 110 111 |
# File 'lib/facebooker2/rails/controller.rb', line 109 def signed_request_from_logged_out_user? !facebook_params.empty? && facebook_params[:oauth_token].nil? end |