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
Related
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 Devise user auth included in my site and it is working well. I'm now trying to add Facebook authentication.
I'm able to login with FB, and the user is redirected back to my site ok. When I check the connected apps in FB settings I can see my site is there listed.
The problem is that the FB is not added to my user table. When I check the db, the provider and uid fields are blank, and site is still asking for the user to sign in.
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :validatable,
has_many :comments
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :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
# 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
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
end
Callback Controller
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
routes.rb
#authentication
devise_for :users, path: "auth", controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations',
unlocks: 'users/unlocks',
omniauth_callbacks: 'users/omniauth_callbacks'
}
User Session Controller
class Users::SessionsController < Devise::SessionsController
respond_to :js
before_action :configure_permitted_parameters, :if => :devise_controller?
protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_in_params
devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
end
end
devise.rb
config.omniauth :facebook, '******', '*************', scope: "email", info_fields: 'email'
Update
Just caught the fact I have fname and lname fields in my user table, so have adjusted user.rb to reflect that:
user.fname = auth.info.fname
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'
I've been trying to figure out how to solve this for hours and can't. I keep getting this error:
Unable to autoload constant OmniauthCallbacksController, expected /Users/omar.amiri/Desktop/rails-devise-roles/app/controllers/omniauth_callbacks_controller.rb to define it
omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def linkedin
auth = env["omniauth.auth"]
#user = User.connect_to_linkedin(request.env["omniauth.auth"],current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.linkedin_uid"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
user.rb.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
def self.connect_to_linkedin(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
return registered_user
else
user = User.create(name:auth.info.first_name,
provider:auth.provider,
uid:auth.uid,
email:auth.info.email,
password:Devise.friendly_token[0,20],
)
end
end
end
end
routes.rb
Rails.application.routes.draw do
root to: 'visitors#index'
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
resources :users
end
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.