'devise', '3.4.1'
'rails', '4.1.8'
ruby '2.1.2'
Reset password works with most users but not with others, I have noticed with these users devise fails to save reset_password_sent_at time.
Point me in the right direction if you can...I will add code if needed, just ask.
#devise.rb
config.reset_password_within = 36.hours
#routes
devise_for :users,
controllers: {
registrations: 'registrations',
confirmations: "confirmations", :omniauth_callbacks => "users/omniauth_callbacks"
}
resources :users
#user.rb
devise :database_authenticatable, :registerable, :validatable,
:recoverable, :rememberable, :trackable, :confirmable, :omniauthable,
:omniauth_providers => [:facebook, :twitter, :google, :linkedin]
Related
i have got weird issue while working with my application.
In My app there will be lot mailer options which is write by own and it works perfectly. I have used Devise gem Authentication and those mails like (registration, forgot password, confirmation) mails are not working. End up with issue
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
# config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
:user_name => ENV['sendgrid_username'],
:password => ENV['sendgrid_password'],
:domain => '*****.com',
:address => 'smtp.sendgrid.net',
:port => 587,
:authentication => :plain,
:enable_starttls_auto => true
}
I dont know why i am getting the devise mailer issue, other custom mailers are working fine.
Completed 500 Internal Server Error in 10789ms (ActiveRecord: 4434.0ms | Allocations: 260142)
Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted. Learn more at):
I have inherited the mail in my custom mailer even though i have got same issue.
class UserMailer < ActionMailer::Base
include Devise::Mailers::Helpers
default from: "default#mydomain.com"
def confirmation_instructions(record, token, opts={})
#token = token
devise_mail(record, :confirmation_instructions, opts)
end
def reset_password_instructions(record, token, opts={})
#token = token
devise_mail(record, :reset_password_instructions, opts)
end
def unlock_instructions(record, token, opts={})
#token = token
devise_mail(record, :unlock_instructions, opts)
end
def email_changed(record, opts={})
devise_mail(record, :email_changed, opts)
end
def password_change(record, opts={})
devise_mail(record, :password_change, opts)
end
# you can then put any of your own methods here
end
I am intergrating Facebook login using device, and after allowing Facebook to get your info it redirects you to the sign up page. Here's my code:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :description, :photo ])
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :first_name, :last_name, :description, :photo ])
end
end
Callback controller
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 #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
And my user model is
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 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.first_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
I'd really appreciate an extra eye on what I'm doing wrong, or where I am missing something. Thanks!
You need to add this column for provider and uid to your users table, i think rails can't match your user :
rails g migration add_provider_and_uid_to_users provider:string uid: string
And try to write me the rails server response it Can help to figure out the bug source
I followed all the instructions in Omniauth's walkthrough.
Note that my User model does not have name or image properties.
I followed the instructions in the Rails tutorial. However, I did have to change this:
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
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
to this:
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
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
an error was being thrown because User doesn't have name or image properties.
That led to a new error:
The #user created in the Omniauth_callbacks_controller is not persisting, so instead of getting signed-in, I'm just getting redirected back to the user sign-up page.
omniauth_callbacks_controller.rb:
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"])
puts "BEFORE IF STATEMENT"
puts #user.inspect
if #user.persisted?
puts "INSIDE IF STATEMENT"
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
puts "AFTER ELSE STATEMENT"
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
Server read out, which includes the puts statement and the #user object. You'll see that most of its fields are nil:
Started GET "/users/auth/facebook" for ::1 at 2015-09-01 20:41:01 +0100
I, [2015-09-01T20:41:01.891561 #7662] INFO -- omniauth: (facebook) Request phase initiated.
Started GET "/users/auth/facebook" for ::1 at 2015-09-01 20:41:01 +0100
I, [2015-09-01T20:41:01.978637 #7662] INFO -- omniauth: (facebook) Request phase initiated.
Started GET "/users/auth/facebook/callback?code=AQBcPU1SSS5908ZaCIgZjKnffSjG0PZTNcoyeSjiTbZDbVZvOKIz_YDoZzijNvfuc5QdIHczQPVAFqv3TMxDPZ_lGdUC3sg6d9iScaBgwVqU6uuoGppV7fAO-Q2ALN48is9-Exkr1o0JF2Yry9nebSxcSEDpBz39jDU0EMxOWCShGwG0CCaKLavOo0GzXzmZr1mpYaUZoBgxHSUdr3rRfhoqYMZOrYAYQeR8DMcAw7WR-C4PNKN9NyMwhzWDFv7mtoneP6dWAd22SNOLmQC64ahgJTFsN76brLl1Xl6HYR0wqjd4LBJeeV4uAumdVWkiIgo&state=0c40e8bcabffe59ec093223f78250db73c9a3d9b7717be97" for ::1 at 2015-09-01 20:41:02 +0100
I, [2015-09-01T20:41:02.098574 #7662] INFO -- omniauth: (facebook) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#facebook as HTML
Parameters: {"code"=>"AQBcPU1SSS5908ZaCIgZjKnffSjG0PZTNcoyeSjiTbZDbVZvOKIz_YDoZzijNvfuc5QdIHczQPVAFqv3TMxDPZ_lGdUC3sg6d9iScaBgwVqU6uuoGppV7fAO-Q2ALN48is9-Exkr1o0JF2Yry9nebSxcSEDpBz39jDU0EMxOWCShGwG0CCaKLavOo0GzXzmZr1mpYaUZoBgxHSUdr3rRfhoqYMZOrYAYQeR8DMcAw7WR-C4PNKN9NyMwhzWDFv7mtoneP6dWAd22SNOLmQC64ahgJTFsN76brLl1Xl6HYR0wqjd4LBJeeV4uAumdVWkiIgo", "state"=>"0c40e8bcabffe59ec093223f78250db73c9a3d9b7717be97"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."provider" = $1 AND "users"."uid" = $2 ORDER BY "users"."id" ASC LIMIT 1 [["provider", "facebook"], ["uid", "10153518057141280"]]
(0.2ms) BEGIN
(0.2ms) ROLLBACK
BEFORE IF STATEMENT
#<User id: nil, email: nil, encrypted_password: "$2a$10$6Ls8Eng6pNFz11sV/AmOuuUdq8JRas33H8UnWAX0YyA...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, provider: "facebook", uid: "10153518057141280">
AFTER ELSE STATEMENT
Redirected to http://localhost:3000/users/sign_up
Completed 302 Found in 93ms (ActiveRecord: 1.1ms)
Started GET "/users/sign_up" for ::1 at 2015-09-01 20:41:02 +0100
Processing by Devise::RegistrationsController#new as HTML
Rendered /Users/makerslaptop91/.rvm/gems/ruby-2.2.0/gems/devise-3.5.1/app/views/devise/shared/_links.html.erb (1.0ms)
Rendered /Users/makerslaptop91/.rvm/gems/ruby-2.2.0/gems/devise-3.5.1/app/views/devise/registrations/new.html.erb within layouts/application (6.9ms)
Completed 200 OK in 55ms (Views: 54.3ms | ActiveRecord: 0.0ms)
Notice the puts inside the 'if' statement was never printed.
routes.rb:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
resources :restaurants do
resources :reviews
end
root to: "restaurants#index"
I'm stumped.
If you remove the :validatable option then it will work.
I am trying to set up facebook login integration with omniauth and devise.
Note that I have a MEMBER model which contains the devise info and a USER model that contains the member profile info (to keep them separate)
On the sign up page, the user has a nested form in the member sign up form and receives all the user data at that time. Once the member is saved, the email value for the saved member is also entered into the user table like so
class Member < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
after_save :update_user
def update_user
user.email = self.email
user.save
end
I have the standard model method for the facebook data processing.....
def self.process_omniauth(auth)
where(provider: auth.provider, uid: auth.uid, email: auth.info.email).first_or_create do |member|
member.provider = auth.provider
member.uid = auth.uid
member.email = auth.info.email
end
end
But of course, in this case, there is no nested form so the 'user' is not instantiated and it throws an error when the update_user method is called on saving the member.
How can I modify this method above to instantiate a new user, when signing up via the facebook pathway?
EDIT: This works.....
def update_user
if User.find_by_member_id(self.id).present?
user.email = self.email
user.save
else
User.create(:email => self.email, :member_id => self.id)
end
end
BUT THIS RESULTS IN A CONSTRAINT ERROR - on email - it already exists in the database. From the logs, the else statement here appears to be attempting to create the user twice.
def update_user
if User.find_by_member_id(self.id).present?
user.email = self.email
user.save
else
User.create(:email => self.email)
end
end
Can anyone explain this? I am suprised I had to pass the foreign key to the user in the else block.
I'm not sure what fields are being stored in the User Model but what you should be doing here that in case of Facebook Callback you should create the User if the Member don't have an user associated with it. i.e your update_user should be something like this:
def update_user
if user.present?
user.email = self.email
user.save
else
User.create(:email => self.email, :member_id => self.id)
/*note that a lot of other information is returned in
facebook callback like First Name, Last Name, Image and
lot more, which i guess you should also start saving to
User Model */
end
end
**** EDIT ******** . You should also check if there is user with the same email and associate that with the member.
def update_user
if user.present?
user.email = self.email
user.save
else
user = User.find_by_email(self.email)
if user
user.update_attribute(:member_id, self.id)
else
User.create(:email => self.email, :member_id => self.id)
end
end
I integrated omniauth-facebook using https://github.com/plataformatec/devise/wiki/OmniAuth%3a-Overview. But I am getting error of :
Could not authenticate you from Facebook because "Invalid credentials".
And in logs, getting this:
Authentication failure! invalid_credentials: OAuth2::Error, : {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}}
I have devise installed. When i click on facebook sign in link, it comes back to devise sign "www.mealnut.com/user/sign_in#=" and gives above error. I checked the solution for "Invalid credentials" on https://github.com/plataformatec/devise/wiki/OmniAuth%3a-Overview and as mentioned there, my app is header set for App Type = Web. Not getting why it is not working.
Also my app is pending review from facebook. But i don't think it is related to this error. Following are the things i did for omniauth-facebook:
Gemfile contains:
gem "omniauth", "~> 1.1.4"
gem 'omniauth-facebook', '1.4.1'
In user model, added:
devise :omniauthable, :omniauth_providers => [:facebook]
attr_accessible :provider, :uid
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
unless user
user = User.create(name:auth.extra.raw_info.name,
provider:auth.provider,
uid:auth.uid,
email:auth.info.email,
password:Devise.friendly_token[0,20]
)
end
user
end
devise.rb
require "omniauth-facebook"
config.omniauth :facebook, "APP_ID", "APP_SECRET", :scope => "offline_access, email"
omniauth.rb:
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], {:provider_ignores_state => true}
end
route.rb:
devise_for :user, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
Omniauth controller:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
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
Can anybody help in this?
Thought I'd chip in here since this came up for me when trying to search for a solution for Could not authenticate you from Facebook because “Invalid credentials”
The problem is with Facebook API version >=2.3 you need to set {token_params: {parse: :json}} to your provider config.
devise.rb
config.omniauth :facebook,
APP_ID,
APP_SECRET,
token_params: { parse: :json } # <----- this line is NB
Answer found on this issue for omniauth-oauth2
UPDATE Aug 2018: The "invalid credentials" issue reoccurred, I had to remove the token_params setting for it to work again - so this may not be an issue anymore
Got it working!
My routes.rb and user.rb were wrong. And changed omniauth.rb too! Here are the previous and after files:
My routes.rb was:
devise_for :user, controllers: { registration: "registration" }
devise_for :user, controllers: { omniauth_callbacks: "omniauth_callbacks" }
So it was calling devise twice. I changed it to:
devise_for :user, controller: { registration: "registration", omniauth_callbacks: "omniauth_callbacks" }
Changed my omniauth.rb from this:
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], provider_ignores_state: true
end
to this:
OmniAuth.config.logger = Rails.logger
Also, i defined method def self.find_for_facebook_oauth(auth, signed_in_resource=nil) outside user.rb model (major mistake).
So got it working perfectly now :-)
Hope this helps someone.
Got it working too :)
We don't need to add this code in omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET']
end
if we already declare it in devise.rb
require "omniauth-facebook"
config.omniauth :facebook, "APP_ID", "APP_SECRET"
It helped me to solve a similar problem:
Note: v2.0.1 has an issue with callback url error. You need to add a callback url on config.
config.omniauth :facebook, "APP_ID", "APP_SECRET",
callback_url: "CALLBACK_URL"
https://github.com/plataformatec/devise/wiki/OmniAuth%3a-Overview
Upgrading gem to 4.0.0 and adding require "omniauth-facebook" to devise.rb fixed this for me.
I stack with this problem and no one advice was help me.
Problem was in redirect_uri. Devise omniauth gems generated it without https.
Finally resolved this by two steps:
Add force_ssl for rails.
Do not forget to add proxy_set_header X-Forwarded-Proto https; for nginx config, if you are using it.