I'm using:
- Ruby on Rails 4
- devise 3.0.3
- omniauth (1.1.4)
- omniauth-facebook (1.4.1)
- omniauth-twitter (1.0.0)
I recently set up my omniauth-facebook
and everything works fine. Now i want to add omniauth-twitter
but somehow i mess things up, pretty bad.
1.) To set up my Omniauth-Facebook
i did this (in a nutshell):
gem 'omniauth'
gem 'omniauth-facebook'
2.) Added the columns "provider
" and "uid
" to my User model.
3.) Next, i declared the provider in my config/initializers/devise.rb:
require "omniauth-facebook"
config.omniauth :facebook, "App_ID", "App_Secret",
{:scope => 'email,offline_access',
:client_options => {:ssl => {:ca_file => 'lib/assets/cacert.pem'}},
:strategy_class => OmniAuth::Strategies::Facebook}
4.) I edited my Model User.rb
# Facebook Settings
def self.find_for_facebook_oauth(auth, signed_in_resource = nil)
user = User.where(provider: auth.provider, uid: auth.uid).first
if user.present?
user
else
user = User.create(first_name:auth.extra.raw_info.first_name,
last_name:auth.extra.raw_info.last_name,
facebook_link:auth.extra.raw_info.link,
user_name:auth.extra.raw_info.name,
provider:auth.provider,
uid:auth.uid,
email:auth.info.email,
password:Devise.friendly_token[0,20])
end
end
and added the attributes to devise:
:omniauth_providers => [:facebook]
5.) I edited the routes:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
THE END
Although this worked perfectly for Facebook, i tried for hours now to get this working for Twitter, and i just cant figure it out.
If someone, who has experience in this, or just knows the solution could help me set this up, i would be very thankful :)
Thank you guys, and sorry for the long Post.
In Addition
Twitter does not provide an :email Attribute so i have to Split up my User Registration Process i guess ?
My Twitter action in my User Model
# Twitter Settings
def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth[:provider], :uid => auth[:uid]).first
unless user
user = User.create(:first_name => auth[:name],
:user_name => auth[:screen_name],
:provider => auth[:provider], :uid => auth[:uid],
:password => Devise.friendly_token[0,20]
)
end
user
end
# build auth cookie hash for twitter
def self.build_twitter_auth_cookie_hash data
{
:provider => data.provider, :uid => data.uid.to_i,
:access_token => data.credentials.token, :access_secret => data.credentials.secret,
:first_name => data.name, :user_name => data.screen_name,
}
end
I had to migrate a confirmable for Users -> How To: Add :confirmable to Users
My Form's Problem, (At Least im getting to this poing now :) )
Mattherick has a good solution for the email but I couldn't get the before_create to work. A callback doesn't play nice with conditional if statements because anything after the comma is meant to be an options hash. Therefore:
Popped me errors.
This how I fixed this:
This will only set an email if one is not given by the provider (ie: Twitter).
And then for a more 'universal' way of setting attributes (so you don't need a unique strategy:
Add this in gem file
do bundle and restart the server
after this add your app_id and secret key in config/initializer/devise.rb
edit your user model
Add new controller file in
end
Add this link in your view file
Changes required in user model as twitter do not return user's email id: Create a migration file to allow null values in user's email column:
after this you also need to override user model validations so add this in user.rb
Note: Before performing this you should create your app on twitter and give proper callback path. Its is important as after authentication from twitter the controller would come back to the path which you specify in your app on twitter.
let me know if you have any problem.
To fix your problem with the email you could just set a dummy mail, or add a second step where the user adds his/her email.
Dummy mail:
Or the second step option:
Modify your controller to redirect to an add email step if the provider is twitter and the email is blank. Maybe you also have to modify your validations to allow email blank on create if the provider is twitter.
UPDATE: I did it like following:
Gemfile:
I used:
If you are using different versions, you maybe must change a few things..
routes.rb:
app/models/user.rb
app/controllers/users/omniauth_callbacks_controller.rb
app/views/users/omniauth_callbacks/add_email.html.erb
app/controllers/users/accounts_controller.rb
Maybe you have to modify the one or other part of my solution..you also could refactor the two methods in the user model (find_for_facebook_auth, find_for_twitter_auth) to work with one dynamic method. Try it out and let me know, if you still have problems. If you find any typo, please also let me know.. Also you should write tests to check everything within your system.