Reputation: 5343
EDIT: I HAVE FOLLOWED THE ANSWER BELOW AND REFRESHED POST BECAUSE I WAS STUCK ELSEWHERE, THE GIVEN ANSWER BELOW IS CORRECT.
Hey guys so i am trying to implement social authentications but i am stuck.
I've setup correctly the callback url both in my routes and google console and i've verified it by displaying the auth_hash in browser.
my session_controller.rb
def google_oauth2
auth_hash = request.env['omniauth.auth']
@user = User.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
if @user
log_in @user
flash[:success] = "Welcome, #{@user.name}!"
else
@user = User.new(
uid: auth_hash['uid'],
provider: auth_hash['provider'],
name: auth_hash['info']['name'],
email: auth_hash['info']['email'],
image_url: auth_hash['info']['image'],
oauth_token: auth_hash['credentials']['token'],
oauth_refresh_token: auth_hash['credentials']['refresh_token'],
oauth_expires_at: auth_hash['credentials']['expires_at']
)
if @user.save
log_in @user
flash[:success] = "Hello, #{@user.name}! An account has been created for you!"
else
flash[:warning] = "There was an error while trying to authenticate you..."
end
end
redirect_to root_path
end
User.model
validates :name,
presence: true,
length: { maximum: 50 }
validates :email,
presence: true,
length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive:false }
has_secure_password
validates :password,
presence:true,
length: { minimum: 8 },
allow_nil: true
And this is the error in console
Started GET "/auth/google_oauth2/callback?state=00407988327c46ec93248da4dadba18c56efc88ef44c36b0&code=4/l666HRBZExC2XR93sI4VP7pWIYAkNySwD75sHtSOb_o" for ::1 at 2015-08-07 02:43:34 +0300
I, [2015-08-07T02:43:34.321568 #6869] INFO -- omniauth: (google_oauth2) Callback phase initiated.
Processing by SessionsController#google_oauth2 as HTML
Parameters: {"state"=>"00407988327c46ec93248da4dadba18c56efc88ef44c36b0", "code"=>"4/l666HRBZExC2XR93sI4VP7pWIYAkNySwD75sHtSOb_o", "provider"=>"google_oauth2"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ? LIMIT 1 [["provider", "google_oauth2"], ["uid", "118084345864130537689"]]
(0.0ms) begin transaction
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
(0.0ms) rollback transaction
Redirected to http://localhost:3000/
Completed 302 Found in 20ms (ActiveRecord: 1.2ms)
The problem is that the error in my session controller fires each time,and no user is created
"There was an error while trying to authenticate you..."
Anyone who can collaborate?
Upvotes: 3
Views: 980
Reputation: 2088
The rescue is most likely caused not because of the @user.save!
, but rather an error from user.uid = auth_hash['uid']
because user
is not set.
Simply remove user.
from all names and it should work.
P.S.
1.You should never use rescue without specifying an error to rescue from(now it just skips every single error that might come up).
Assigning all parameters to variables is unnecessary. Use them directly
You should really refactor most of this code. Most of your controller code should go into the model.
My Version of your code would be something like this:
session_controller.rb
def google_oauth2
auth_hash = request.env['omniauth.auth']
if User.from_omniauth(auth_hash)
session[:user_id] = @user.id
flash[:success] = "Welcome, #{@user.name}!"
redirect_to root_path
else
User.new(uid: auth_hash['uid'],
provider: auth_hash['provider'],
name: auth_hash['info']['name'],
email: auth_hash['info']['email'],
image_url: auth_hash['info']['image'])
if @user.save!
flash[:success] = "Welcome, #{@user.name}!You've signed up!"
else
flash[:warning] = "There was an error while trying to authenticate you..."
end
end
redirect_to root_path
end
user.rb
def self.from_omniauth(auth_hash)
find_by(uid: auth_hash['uid'], provider: auth_hash['provider'])
end
But it would be even better if you put all of the code for creating a user in the model as well.
Upvotes: 2