Devise - Omniauth - Facebook - Getting Extra Permissions


Programming in Ruby tutorials and examples

Devise - Omniauth - Facebook - Getting Extra Permissions


When using devise and omniauth for authentication sometimes you need to require more permissions from facebook. This is useful when you want to later use the authentication code from facebook do such things as posting to the users wall (I recommend the Koala Gem for this).

Within the devise config you will probably already have your facebook omniauth provider setup. After passing the secret key you just need to pass a scope requesting the additional permissions required for your application.

config/initializers/devise.rb
1
  config.omniauth :facebook, 'app_id', 'secret_key', { :scope => "publish_stream, offline_access, email" }

When your user is now setup or authorized from facebook make sure you save the code parameter against the user, this is passed back to your omniauth callbacks controller. Here is an example of mine below.

app/controllers/users/omniauth_callbacks_controller.rb
1
2
3
4
5
6
7
8
9
 class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   include Devise::Controllers::Rememberable

   def facebook
     @user = User.configure_facebook_user(request.env["omniauth.auth"], params[:code])
     remember_me @user
     sign_in_and_redirect @user, :event => :authentication
   end
 end

Also below I have included my class methods from my user model that takes care of saving the user (I hope this helps someone).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def facebook_config
  YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
end

def facebook_client(access_token)
   Koala::Facebook::API.new(access_token)
end

def configure_facebook_user(authorisation_hash, code)
  user = User.where(:email => authorisation_hash.info.email).first

  unless user
    user = User.create(:email => authorisation_hash.info.email,
                       :first_name => authorisation_hash.extra.raw_info.first_name,
                       :last_name => authorisation_hash.extra.raw_info.last_name,
                       :gender => Gender[authorisation_hash.extra.raw_info.gender.to_sym],
                       :date_of_birth => nil,
                       :location => authorisation_hash.extra.raw_info.hometown.name,
                       :about => authorisation_hash.extra.raw_info.bio,
                       :password => Devise.friendly_token[0,20]
                      )
  end
  user.role = Role[:member] unless user.role
  begin
    user.token = User.facebook_oauth_client.get_access_token(code)
  rescue
    #External api call rescue all!
  end
  user.provider = authorisation_hash.provider
  user.uid = authorisation_hash.uid
  user.save
  user.confirm!
  user.remember_me!
  user
end

def facebook_oauth_client
  Koala::Facebook::OAuth.new(User.facebook_config['app_id'],
                             User.facebook_config['secret_key'],
                             "#{User.facebook_config['callback']}/users/auth/facebook/callback")
end

Comments