Pulling my hair out on this : being redirected to user/sign_up - here is my code:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable, :omniauth_providers => [:facebook]
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
## user.image = auth.info.image # assuming the user model has an image
end
end
end
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
omniauth = request.env["omniauth.auth"]
#user ||= User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
Rails.logger.level = 0
logger.debug "Session: #{#session.inspect}"
logger.debug "USer: #{#user.inspect}"
logger.debug "Omniauth: #{#omniauth.inspect}"
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
And here is the relevant logger output:
Session: nil
Processing by Devise::RegistrationsController#new as HTML
USer: #
Omniauth: nil
Redirected to http://secret-brushlands-1375.herokuapp.com/users/sign_up
Not sure what to make of this - the Facebook link is fine but my guess is the omniauth hash should not be nil and same of the session... ANy help appreciated.
Related
I am signing in users only from facebook with Omniauth
** Users::OmniauthCallbackController**
class Users::OmniauthCallbacksController <
Devise::OmniauthCallbacksController
def facebook
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication
set_flash_message(:notice, :success, :kind => "Facebook") if
is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to games_path
end
end
but when i try to get current_user to another contoller it always returns nil.
I have read that devise has a built in function for current_user but that didn t seem to work properly(also returned nil every single time) so i implemented another method.
current_user helper
before_action :define_current_user
def current_user
User.find_by id: session["current_user_id"]
end
helper_method :current_user
How can i make it work?
User.rb
class User < ApplicationRecord
belongs_to :team
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :rememberable, :trackable,:validatable
,:omniauthable, :omniauth_providers => [:facebook]
def self.new_with_session(params,session)
super.tap do |user|
if data = session["devise.facebook_data"] &&
session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
#Saving new user to the database
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do|user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name
user.image = auth.info.avatar
user.save!
end
end
end
Don't forget to add before_action :authenticate_user! callback to needed controllers. In this case you'll be able to get value of default current_user from Devise
I have a problem with both gems, because when I try to connect to my webpage with Facebook (Sign Up or Login) tell me they send a email confirmation or I need to confirm the email confirmation.
But the problem is that never send me a email, and other thing, if I don't want send a email when I Sign in my web across Facebook.
I put the code.
app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable, :omniauth_providers => [:facebook]
validates :fullname, presence: true, length: {maximum: 50}
has_many :rooms
has_many :reservations
has_many :guest_reviews, class_name: "GuestReview", foreign_key: "guest_id"
has_many :host_reviews, class_name: "HostReview", foreign_key: "host_id"
def self.from_omniauth(auth)
user = User.where(email: auth.info.email).first
if user
return user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.fullname = auth.info.name
user.image = auth.info.image
user.uid = auth.uid
user.provider = auth.provider
# If you are using confirmable and the provider(s) you use validate emails,
# uncomment the line below to skip the confirmation emails.
user.skip_confirmation!
end
end
end
end
I have a rails app and I want to make a Github connect. I have followed the devise tutorial about Facebook and adapted it for Github.
I have this error on the callback, when accessing /users/auth/github/callback?code=xxxxxxx
ActionController::RoutingError (uninitialized constant Users):
I know that other posts are related to this issue but their answer do not fix my problem.
routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def github
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Github") if is_navigational_format?
else
session["devise.github_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:github]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.github_data"] && session["devise.github_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
end
I am using facebook-omniauth to authenticate user with Facebook. Everything works fine, except how can I build user profile table from extra fields that I receive from omniauth.
The relationship user to profile is has_one, and belongs_to as vice versa.
Following were my OmniauthCallbacksController
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
In my user.rb model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook]
has_many :products
has_one :profile
has_one :store_setting
after_create :send_welcome_message
enum status: {
normal: 0,
merchant: 1
}
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
logger.info "status=from_omniauth first_name=#{auth.info.first_name} first_last_name=#{auth.info.last_name}"
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.build_profile(auth)
#user.name = auth.info.name # assuming the user model has a name
#user.image = auth.info.image # assuming the user model has an image
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
def build_profile(auth)
self.Profile.new(first_name:auth.info.first_name) --> not work!!
end
private
def send_welcome_message
UserMailer.welcome_message(self).deliver
end
end
Thanks!!
It seems that you are trying to override a method buide_profile which gives us Active Record Methods Added by has_one.
Methods Added by has_one
association(force_reload = false)
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
create_association!(attributes = {})
In your case you could re-write from_omniauth methods
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
logger.info "status=from_omniauth first_name=#{auth.info.first_name} first_last_name=#{auth.info.last_name}"
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.build_profile(first_name: auth.info.first_name)
#user.name = auth.info.name # assuming the user model has a name
#user.image = auth.info.image # assuming the user model has an image
end
end
Hope this help you!!!
My Rails app when I tried to integrate gem "omniauth-facebook" with devise, I receive the following error on facebook: The redirect_uri URL must be absolute.
Following were my config
devise.rb
config.omniauth :facebook, "ID", "SECRET",callback_url: "/auth/facebook"
My user.rb model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
user.image = auth.info.image # assuming the user model has an image
end
end
end
My routes:
devise_for :users, :controllers => {:omniauth_callbacks => "users/omniauth_callbacks"}
And Controller OmniauthCallbacksController
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
What am I missing here?
Adding
:client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}
To config.omniauth in the initializer solved the issue for me.
I also configured the path to be absolute like so:
callback_url: ENV['SERVER_ROOT']+'/users/auth/facebook/callback'