Skip to content
This repository

Updated the facebook login_from to allow logins using the Facebook JavaScript SDK #350

Merged
merged 3 commits into from over 1 year ago

4 participants

Michel Billard Pier-Hugues Pellerin Andre Di Genova Noam Ben Ari
Michel Billard

The login_from for Facebook now allows users to login using an access token directly instead of using the code parameter. This allows login via the Facebooj JS SDK (FB.login).

To easily integrate the client side behavior, you can just hijack the click on the facebook button like so (in CoffeeScript):

# assumes that the Facebook JS SDK has been loaded beforehand
$('#facebook-sign-in').on "click", (e) ->
  e.preventDefault()
  FB.login (response) ->
    window.location = "/auth/facebook/callback?access_token=#{response.authResponse.accessToken}&expires_in=#{response.authResponse.expiresIn}" if response.authResponse
Pier-Hugues Pellerin
ph commented November 08, 2012

Anyone else is using this? i'll give it a shot this week.

Michel Billard

I don't think so, but it seems like a fairly standard use case. I've been using the code above for a while now and haven't had any issue.

Andre Di Genova

I need this use case and have hacked it in to my own local copy. Would love to see this pulled.

Noam Ben Ari NoamB merged commit 0e59abe into from January 12, 2013
Noam Ben Ari NoamB closed this January 12, 2013
Noam Ben Ari
Owner

Had to revert some of this to make tests pass again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
18  lib/sorcery/controller/submodules/external/protocols/oauth2.rb
@@ -19,11 +19,21 @@ def authorize_url(options = {})
19 19
             end
20 20
 
21 21
             def get_access_token(args, options = {})
  22
+              raise ArgumentError, "either a `code` or an `access token` is necessary to build an Oauth2 AccessToken" if args[:code].nil? && args[:access_token].nil?
  23
+
22 24
               client = build_client(options)
23  
-              client.auth_code.get_token(
24  
-                args[:code],
25  
-                { :redirect_uri => @callback_url, :parse => options.delete(:parse) }, options
26  
-              )
  25
+
  26
+              if args[:access_token]
  27
+                hash = args
  28
+                hash.merge!({:mode => options[:mode]}) if options[:mode]
  29
+                hash.merge!({:param_name => options[:param_name]}) if options[:param_name]
  30
+                ::OAuth2::AccessToken.from_hash(client, hash)
  31
+              else
  32
+                client.auth_code.get_token(
  33
+                  args[:code],
  34
+                  { :redirect_uri => @callback_url, :parse => options.delete(:parse) }, options
  35
+                )
  36
+              end
27 37
             end
28 38
 
29 39
             def build_client(options = {})
27  lib/sorcery/controller/submodules/external/providers/facebook.rb
@@ -16,7 +16,7 @@ def self.included(base)
16 16
               base.module_eval do
17 17
                 class << self
18 18
                   attr_reader :facebook                           # access to facebook_client.
19  
-                  
  19
+
20 20
                   def merge_facebook_defaults!
21 21
                     @defaults.merge!(:@facebook => FacebookClient)
22 22
                   end
@@ -25,7 +25,7 @@ def merge_facebook_defaults!
25 25
                 update!
26 26
               end
27 27
             end
28  
-          
  28
+
29 29
             module FacebookClient
30 30
               class << self
31 31
                 attr_accessor :key,
@@ -39,7 +39,7 @@ class << self
39 39
                 attr_reader   :access_token
40 40
 
41 41
                 include Protocols::Oauth2
42  
-            
  42
+
43 43
                 def init
44 44
                   @site           = "https://graph.facebook.com"
45 45
                   @user_info_path = "/me"
@@ -51,7 +51,7 @@ def init
51 51
                   @parse          = :query
52 52
                   @param_name     = "access_token"
53 53
                 end
54  
-                
  54
+
55 55
                 def get_user_hash
56 56
                   user_hash = {}
57 57
                   response = @access_token.get(@user_info_path)
@@ -59,31 +59,38 @@ def get_user_hash
59 59
                   user_hash[:uid] = user_hash[:user_info]['id']
60 60
                   user_hash
61 61
                 end
62  
-                
  62
+
63 63
                 def has_callback?
64 64
                   true
65 65
                 end
66  
-                
  66
+
67 67
                 # calculates and returns the url to which the user should be redirected,
68 68
                 # to get authenticated at the external provider's site.
69 69
                 def login_url(params,session)
70 70
                   self.authorize_url
71 71
                 end
72  
-                
  72
+
73 73
                 # tries to login the user from access token
74 74
                 def process_callback(params,session)
75 75
                   args = {}
76 76
                   options = { :token_url => @token_url, :mode => @mode, :param_name => @param_name, :parse => @parse }
  77
+
  78
+                  # server side callback params
77 79
                   args.merge!({:code => params[:code]}) if params[:code]
  80
+
  81
+                  # client side callback params
  82
+                  args.merge!({:access_token => params[:access_token]}) if params[:access_token]
  83
+                  args.merge!({:expires_in => params[:expires_in]}) if params[:expires_in]
  84
+
78 85
                   @access_token = self.get_access_token(args, options)
79 86
                 end
80  
-                
  87
+
81 88
               end
82 89
               init
83 90
             end
84  
-            
  91
+
85 92
           end
86  
-        end    
  93
+        end
87 94
       end
88 95
     end
89 96
   end
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.