Skip to content

Instantly share code, notes, and snippets.

@PanosJee
Created March 17, 2011 22:58
Show Gist options
  • Save PanosJee/875320 to your computer and use it in GitHub Desktop.
Save PanosJee/875320 to your computer and use it in GitHub Desktop.
Login / Register to Refinery with Omniauth (facebook, twitter, openid, etc)
# Create a role user (no perms). Fire up the console rails c
$> Role.create(:title=>'User')
# In your Gemfile add
gem 'oa-oauth', :require => 'omniauth/oauth'
# At the beginning of devise.rb. You can also create a yaml file and instantiate when Rails begin
# For shake of simplicity I added the credentials at devise.rb
Facebook = Rails.env.development? ? {:app_id => 2621xxx, :secret => 'e81f33d042xxxxx'} :
{:app_id => 1749xxx9, :secret => '13c11be6628dc1xxxx'}
# In devise.rb inside the config block
config.omniauth :facebook, Facebook[:app_id], Facebook[:secret] , {
:scope => "email,offline_access,share_item, status_update, user_birthday"}
# rake refinery:override controller=registrations
# 1. We need to create a username so that we comply with the validation
# After line 15 we may add the following, if we have an email
@user.username = @user.email.split('@')[0]
# By default refinery adds the refinery role when somebody registers.
# We keep this behaviour only for the first user. At line 20 we add:
if !refinery_users_exist?
@user.add_role(:refinery)
@user.plugins = @selected_plugin_titles
else
@user.add_role(:user)
end
# Then at line 55 we modify the redirect? method
# We remove the condition refinery_users_exist?
def redirect?
if refinery_user?
redirect_to admin_users_url
end
end
# We edit routes.rb as following
devise_for :users, :controllers => {
:registrations => "users",
:sessions=>"sessions",
:omniauth_callbacks => "users/omniauth_callbacks"
}, :stateless_token => false
match "/registrations/auth/facebook" => redirect("/users/auth/facebook")
# We add somewhere in our views the Login with Facebook button
<%= url_for users_auth_facebook_path(:facebook) %>
# We then create the controller users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model
@user = User.find_for_facebook_oauth(env["omniauth.auth"], current_user)
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.facebook_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
# And finally we add the following method to user.rb
# Of course the Facebookdata contains different data according to the permissions
# we set at devise.rb (omniauth config).
# Do not forget we need a password for devise (so we create a random one) and a
# a password. We also need to store the Facebook token if we need offline access
# If you ask for more user data then you should modify your user table accordingly
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token['extra']['user_hash']
if user = User.find_by_email(data["email"])
user
else # Create an user with a stub password.
user = User.new(:email => data["email"], :password => Devise.friendly_token[0,20],
:username => data['name'], :first_name=>data['first_name'],
:last_name=>data['last_name'],:birthday => data['birthday'],
:gender => data['gender'], :uid => data['id'],
:token => access_token['credentials']['token'])
user.add_role(:user)
user.save!
end
end
# For this example we create the following migration
class AddFieldsToUser < ActiveRecord::Migration
def self.up
add_column :users, :uid, :bigint, :limit => 30
add_column :users, :token, :text
add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :birthday, :date
add_column :users, :gender, :string, :limit => 15
remove_column :users, :password_salt
end
def self.down
remove_column :users, :uid
remove_column :users, :token
remove_column :users, :first_name
remove_column :users, :last_name
remove_column :users, :birthday
remove_column :users, :gender
add_column :users, :password_salt
end
end
@PanosJee
Copy link
Author

PanosJee commented Mar 17, 2011 via email

@freemarmoset
Copy link

I did create the users/ominiauth_...callbacks and setup devise.rb

config.omniauth :facebook, Facebook[:app_id], Facebook[:secret]

wasn't worried about scope for my case. The callback route is recognized. It's the initial login /users/auth/facebook is what isn't picked up for some reason.

@jcmendez
Copy link

@omeryavuz
Copy link

registrations changed users so you must run this command
rake refinery:override controller=users

@omeryavuz
Copy link

Also you must change following items
for user login
<%= url_for users_auth_facebook_path(:facebook) %>

on routes.rb

devise_for :users, :controllers => {
:registrations => "users",
:sessions=>"sessions",
:omniauth_callbacks => "users/omniauth_callbacks"
}, :stateless_token => false

match "/users/auth/facebook" => redirect("/users/auth/facebook")

Thanks for your effort.

@PanosJee
Copy link
Author

PanosJee commented Jun 13, 2011 via email

@dennismonsewicz
Copy link

After adding in @omeryavuz latest code I am getting nasty redirect loop issues... anyway of fixing this?

Link:

<%= link_to "Sign in with Olympus", users_auth_olympus_path %>

Routes.rb:
devise_for :users, :controllers => {
:registrations => "users",
:sessions=>"sessions",
:omniauth_callbacks => "users/omniauth_callbacks"
}, :stateless_token => false

devise_scope :users do
match "/users/auth/olympus" => redirect("/users/auth/olympus")
end

Olympus is the name of a 3rd party oauth system I have built

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment