I am unable to access the user email through facebook authentication.
my code in authentication controller
def facebook
omni= request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omni['provider'],omni['uid'])
if authentication
flash[:notice]="Logged in successfully"
sign_in_and_redirect User.find(authentication.user_id)
elsif current_user
token=omni['credentials'].token
token_secret=omni['credentials'].secret
current_user.authentications.create!(:provider=>omni['provider'],:uid=>omni['uid'],:token=>token,:token_secret=>token_secret)
flash[:notice]="Authentication successful."
sign_in_and_redirect current_user
else
user=User.new
# user.email=omni['extra']['raw_info'].email
user.apply_omniauth(omni)
if user.save
flash[:notice]="Logged in."
sign_in_and_redirect User.find(user.id)
else
session[:omniauth]=omni.except('extra')
redirect_to new_user_registration_path
end
end
end
devise.rb
config.omniauth :facebook, 'xxxxxxxxxxxxxxx851','xxxxxxxxxxxxxxxxxxd47aae3', {:scope => ' email,publish_stream,offline_access' ,:display => 'popup'}
in user model
def apply_omniauth(omni)
authentications.build(:provider => omni['provider'],
:uid=>omni['uid'],
:token=>omni['credentials'].token,
:token_secret=>omni['credentials'].secret,
)
x=omni["info"]["name"].split # split the full name into first and last name
self.first_name=x[0]
self.last_name=x[1]
self.profile_name=omni['info']['nickname']
end
Is their something in the code?
Last, I remember, email can be found at omni.info.email.
Also, I advice you to use . notation here, instead of hash.
Related
I'm getting the following error when trying to sign in through google+ using the google_oauth2 gem.
undefined method `find_for_google_oauth2' for #<Class:0x007ff70a337148>
Here's the three files I've altered for sign up.
user.rb
def google_oauth2
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash.notice = "Signed in Through Google!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
flash.notice = "You are almost Done! Please provide a password to finish setting up your account"
redirect_to new_user_registration_url
end
end
omniauth_callbacks_controller.rb
def google_oauth2
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
and I've added config.omniauth :google_oauth2 in my devise.rb file.
routes.rb
devise_for :users, :controllers => { :registrations => "registrations", :sessions => "sessions", :omniauth_callbacks => "users/omniauth_callbacks" }
You are calling find_for_google_oauth2 from the omniauth_callbacks_controller, but you are using the wrong method name google_oauth2. You should replace google_oauth2 with find_for_google_oauth2.
And it seems like the code in user.rb is incorrect because it contains the controller code. Do you see it looks exactly the same like your controller code? :)
Correct code for user.rb
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
data = access_token.info
user = User.where(:email => data["email"]).first
# Uncomment the section below if you want users to be created if they don't exist
# unless user
# user = User.create(name: data["name"],
# email: data["email"],
# password: Devise.friendly_token[0,20]
# )
# end
user
end
Read more here: https://github.com/zquestz/omniauth-google-oauth2#devise
I'm trying to integrate Devise with Omniauth and have some troubles with them both. The main problem is to bind Devise User model with Omniauth authentications. I want a simple way to associate my user, with external providers like facebook, twitter, g+ and so on.
One of the most annoying issues that arise with my application is:
If an user registered on my site with devise (I call it local user), that means, provided an email and a password, when user tries to login with twitter, the system asks for mail confirmation. If that mail already exists, then user have to provide another mail. I want instead that he can confirm with a password that it is actually his email. How to do that? How can I override that template?
This is my authentications controller:
class AuthenticationsController < ApplicationController
def index
#authentications = Authentication.all
end
def create
#authentication = Authentication.new(params[:authentication])
if #authentication.save
redirect_to authentications_url, :notice => "Successfully created authentication."
else
render :action => 'new'
end
end
def destroy
#authentication = Authentication.find(params[:id])
#authentication.destroy
redirect_to authentications_url, :notice => "Successfully destroyed authentication."
end
def twitter
omni = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])
if authentication
flash[:notice] = "Logged in Successfully"
sign_in_and_redirect User.find(authentication.user_id)
elsif current_user
token = omni['credentials'].token
token_secret = omni['credentials'].secret
current_user.authentications.create!(:provider => omni['provider'], :uid => omni['uid'], :token => token, :token_secret => token_secret)
flash[:notice] = "Authentication successful."
sign_in_and_redirect current_user
else
user = User.new
user.apply_omniauth(omni)
if user.save
flash[:notice] = "Logged in."
sign_in_and_redirect User.find(user.id)
else
session[:omniauth] = omni.except('extra')
p session
redirect_to new_user_registration_path
end
end
end
end
I also have no idea where new_users_registration_path is.
I'm using Omniauth to try to signup/login users on my web app.
This is happening inside my AuthenticationsController#Create method:
Authentications Controller:
class AuthenticationsController < InheritedResources::Base
def create
omniauth = request.env['omniauth.auth']
authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
if authentication
flash[:success] = "Signed in successfully"
sign_in_and_redirect(authentication.user)
elsif current_user
token = omniauth['credentials'].token
secret = omniauth['credentials'].secret
current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'], :token => token, :secret => token_secret)
flash[:success] = "Authentication successful"
redirect_to authentications_url
else
user = User.new
user.apply_omniauth(omniauth)
if user.save!
flash[:success] = "Account created"
sign_in(authentication.user)
else
session[:omniauth] = omniauth.except('extra')
redirect_to '/signup'
end
end
end
I originally had sign_in(:user, authentication.user) but it gave me argument errors, so I changed it to just had sign_in(authentication.user) in the above code. However, now I'm getting a NoMethodError - undefined method 'user' for nil:NilClass.
Line 23 sign_in(authentication.user) is failing because you are in the else branch of if authentication condition (so authentication is nil).
What you probably meant to do is call sign_in(user) for user you just created a few lines above.
First you test if authentication is defined, and then in the else block, which will only trigger if it is not defined, you go and reference authentication.user for some reason. This could not possibly work.
That condition seems to apply if you haven't authenticated, and aren't logged in. Why would you be engaging the sign_in function under those circumstances?
If your using a set list of providers in your db make sure
> :provider => omniauth['provider']
Matches up with the provider in the db, for instance. If you have facebook_Oauth2 in your db and the provider response is facebook authenthication will fail.
I have Google Omniauth 2 correctly authorizing, pulling the email, creating the users and logging in.
However, each time I log out and click my "Log In With Google" link - it directs me to the Google Allow Access page and makes me approve it again and then logs me in.
Is this just how google operates? Is there a way to pass a scope to make it not ask each time?
Here is my omniauth initializer
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, '####', '####', :scope => 'email,offline_access', :display => 'popup'
provider :google_oauth2, '####.apps.googleusercontent.com', '#####', { }
end
Here is my sessions controller:
class SessionsController < ApplicationController
def create
auth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
session[:user_id] = user.id
#redirect_to root_url, :notice => "Signed in!"
redirect_back_or user
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Signed out!"
end
end
I am using Devise with Omniauth to have users sign into my app with Facebook. I used the Railscast tutorials to get it up and running.
If a user is already a member of my site authenticating through facebook works fine. The problem comes in when authenticating a new user with facebook. When it goes to create a new user for my User model I get the "users.encrypted_password may not be NULL" error. I can't figure out how to pass over the password to the User model from Facebook information.
This is what I have:
authentations_controller.rb
class AuthenticationsController < ApplicationController
def index
#authentications = current_user.authentications if current_user
end
def create
omniauth = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
if authentication
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, authentication.user)
elsif current_user
current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
flash[:notice] = "Authentication successful."
redirect_to authentications_url
else
user = User.new
user.apply_omniauth(omniauth)
if user.save
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, user)
else
session[:omniauth] = omniauth.except('extra')
redirect_to new_user_registration_url
end
end
end
user.rb
def apply_omniauth(omniauth)
self.email = omniauth['user_info']['email'] if email.blank?
authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'])
end
def password_required?
(authentications.empty? || !password.blank?) && super
end
Any help would be great, thanks in advance!
Add :password => Devise.friendly_token[0,20] when creating a new user from facebook omniauth.
I believe Devise is expecting something in the password field to create a User. Since there is no password when doing facebook oauth (not on your app side at least), you just need to create a dummy password as show above.
See this for more info:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview