-
-
Save PanosJee/875320 to your computer and use it in GitHub Desktop.
# 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 | |
Thank you very much for putting that together. This is pretty close to what I have. For some reason there is no route matching "/users/auth/facebook". That falls through to refinery's default pages route. Don't know if that is something you ran across when you were first implementing or not? Any insight there? I'll keep plugging at it and let you know what I find. Thanks again.
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.
@freemarmoset -- maybe this link helps? https://github.com/plataformatec/devise/issues/closed#issue/916
registrations changed users so you must run this command
rake refinery:override controller=users
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.
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
I have written the code about 2 months back so I do not fully remember. If you encounter any bugs please fork away and fix it.
Thanks