This is an update to my last post about Facebook Connect with a Rails app. At the time I was using facebooker plugin (yeah, a plugin, not a gem), which has been discontinued for the longest time, and thus wouldn’t work with current Facebook connect.
Since then, I’ve used omniauth, omniauth-facebook, and devise gems to implement Facebook connect with a few Rails app I have been toying with. So, this is kind of an update to my last post about integrating Facebook Connect with a Rails app.
1. First, you need the following gems in your Gemfile.
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'oauth2'
Make sure you install them by running “bundle install” command.
2. Next configure devise gem.
rails generate devise:install
3. Apply devise to a model. 99.9% of time, this would be the User model.
rails generate devise User
4. Next, generate authentication model with the following columns. Token column is extra, if you want to save an access token.
rails g model Authentication user_id:integer provider:string uid:string token:string
5. Configure omniauth by modifying config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
# The following is for facebook
provider :facebook, [APP ID], [SECRET KEY], {:scope => 'email, read_stream, read_friendlists, friends_likes, friends_status, offline_access'}
# If you want to also configure for additional login services, they would be configured here.
end
6. After user authenticates with whatever provider you specify, user needs to be redirected to omniauth call, so add the following line in your routes.rb.
match '/auth/:provider/callback' => 'authentications#create'
7. Then in Authentications controller, you figure out whether to create a new user or log the user in, if the user is an existing user. For complete hash, take a look at omniauth-facebook github page.
def create
auth = request.env["omniauth.auth"]
# Try to find authentication first
authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
# Authentication found, sign the user in.
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, authentication.user)
else
# Authentication not found, thus a new user.
user = User.new
user.apply_omniauth(auth)
if user.save(:validate => false)
flash[:notice] = "Account created and signed in successfully."
sign_in_and_redirect(:user, user)
else
flash[:error] = "Error while creating a user account. Please try again."
redirect_to root_url
end
end
end
8. In User model, store essential information with apply_omniauth method.
has_many :authentications, :dependent => :delete_all
def apply_omniauth(auth)
# In previous omniauth, 'user_info' was used in place of 'raw_info'
self.email = auth['extra']['raw_info']['email']
# Again, saving token is optional. If you haven't created the column in authentications table, this will fail
authentications.build(:provider => auth['provider'], :uid => auth['uid'], :token => auth['credentials']['token'])
end
9. In Authenication model,
belongs_to :user
10. In your view, user clicking on /auth/facebook/ link will be redirected to Facebook to log in.
<%= link_to 'Login with Facebook', '/auth/facebook/' %>
I know this site offers quality depending content and extra stuff, is there any other site which offers these kinds of data in quality?
Pingback: metin2 hack
Great! Thanks for the update
Pingback: best service
Thanks for the update, it was really useful..
Can you post a similar article about getting connected with twitter??
Pingback: How to integrate Facebook Feed with a Rails app « Yangtheman
Pingback: How to integrate Facebook Connect with a Rails app « Yangtheman
i m getting bellow error
Bundler could not find compatible versions for gem “oauth2”:
In Gemfile:
omniauth-facebook (>= 0) ruby depends on
oauth2 (~> 0.5.0) ruby
oauth2 (0.4.1)
please give solution
Delete Gemfile.lock and do “bundle install” again.
This is an excellent guide but does not seem to work in the following 2 cases.
1. User is already logged in but did have that specific authentication.
2. There exists an user who already registered to the application with the email address that will be used on the facebook. This cause duplicate error in the db, and fails to proceed.
Thanks for this article, it’s really cool and usefull.
But,
I’m getting this error when try to connect with facebook:
{
“error”: {
“message”: “Invalid redirect_uri: La URL indicada no esta permitida por la configuraci\u00f3n de la aplicaci\u00f3n.”,
“type”: “OAuthException”,
“code”: 191
}
}
in my initializer omniaguth.rb i just have this:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, “335194483202896”, “608a8277064afd99d2c563c7d5a43e89”
end
also i added the redirect uri on the omniauth.rb:
provider :facebook, “335194483202896”, “608a8277064afd99d2c563c7d5a43e89”, :redirect_uri => “http://reelo.dev/auth/facebook/callback”
but, I still getting the same error
thanks for your help
You shouldn’t need to specify redirect_url in the omniauth.rb. Just add the following line in the routes.rb.
Also, if you are testing it locally, you should make sure that you modify your hosts file to point your root domain to the loopback address.
match ‘/auth/:provider/callback’ => ‘authentications#create’
Is that a typo? it should be ‘authentication#create’ ?
It’s plural because there could be many authentication methods such as twitter, google, etc.
thanks!
great!
Hello! Nice post!
I am getting the this error:
/config/initializers/omniauth.rb:3: uninitialized constant ID (NameErro
r)
can you help?
thanks!
Nervermind man…
forgot to edit the app_id and the app_secret of my application.
thanks!!!
great post!!
Is there a way to get the info, especially hometown, localized from Facebook? For example, I get “Munich, Germany” which would have to be “München, Deutschland”.
Not sure….. Sorry! :(
Great one thanks ..
One questions .
How should i access public fb info for the user id now ?
say username , photo url etc .
Interested in this, too! After authentication, how do I access the FB Graph API?
Hey, check out the fb_graph gem. Good stuff.
https://github.com/nov/fb_graph
Pingback: 关于的Devise+omniauth的用法文章搜集 | David's Blog
Thanks for the tutorial,
but i have a problem. When i’m connecting with facebook, devise wants to confirm the account. How skip the confirmation email, please ?
You can do it in two ways.
Either remove :confirmable from user model, or
Before saving the user instance, do “user.skip_confirmation!” followed by “user.save”.
I keep getting this. What am I doing wrong?
{
“error”: {
“message”: “Invalid redirect_uri: Given URL is not permitted by the application configuration.”,
“type”: “OAuthException”,
“code”: 191
}
}
Add the following line to your /etc/hosts file, and click on facebook connect from http://your_custom_domain.com:3000. You don’t have to have domain name purchased to test this.
Also make sure your “site URL” in facebook app configuration (https://developers.facebook.com/apps) is “http://your_custom_domain.com”.
hi in my app i am using devise for authentication and for facebook authentication i followed u r tutorial described above…..
but i m getting problem
Routing Error
No route matches [GET] “/auth/facebook”
Try running rake routes for more information on available routes.
but
after runing rake routes i got
/auth/:provider/callback(.:format) auth/:provider#callback
its there
my routes.rb
match ‘/users/auth/:provider/callback’ ; ‘authentications#create’
devise_for :admins,:controllers => {:sessions => “admin_sessions”,:registrations => “admin_registrations”,:passwords => “admin_passwords”,:confirmations => “admin_confirmations”}
devise_scope :admins do
match “/admins/admin_login_checking_at_sign_in”,:to =>”admins#admin_login_checking_at_sign_in”,:as=> “admin_login_checking_at_sign_in”
end
please help me out…..
looking for u r reply
thanks in advance
Works perfect for me and the timing is great too!
Keep on writing about your Rails programming, please!!
Hii is there any way that while coming the error it should not empty the email field if that have error
Thanks for your post. It is very helpful. I’m getting the following error: Could not find a valid mapping for # is OK
I followed the steps in your blog without understanding omniauth. I’d appreciate any clues to what may be causing this issue. Thanks again!
The error is: Could not find a valid mapping for #<User id: 1,1, name: "[myName]", uid: [myUid], created_at: "2012-12-10 23:49:28",….
I meant to say that User.all produces the correct results. Thanks!
The step were it fails is: sign_in_and_redirect(:user, user)
Hi, Thanks for the guide, but I am missing the “config/initializers/omniauth.rb” file on step 5 for some reason…
Oh, you have to create it yourself.
Is there a reason to separate authentication from user and to use the omniauth.rb instead of directly integrating with devise.rb?
I ask this because the devise wiki guide (https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview) just puts everything in devise.rb and the user.
Where do you create the route for ‘/auth/facebook/’?
Also, do you have a repo for this as an example?
Hi guys,
I have just created an working demo app following this.
You can now clone and start using it for developing your own applications.
https://github.com/klebershimabuku/fb_auth_demo
If you clone, please let me know by starring the repo.
Hope this helps you!
How to sign out from application
This move transforms Facebook from being a social
network to being quasi-White Pages of the Web. But when people click on your search listing, they wont be able to see
all of the information in your profile (timeline).
Facebook messages can be open for all to see, and even private messages can be viewed by authorities through search
warrants in more open countries or pressure on the Internet social
media firms in more closed ones.