Petros Kyriakou
Petros Kyriakou

Reputation: 5343

Omniauth and google oauth2 error without Devise - Rails 4

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

Answers (1)

Kkulikovskis
Kkulikovskis

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).

  1. Assigning all parameters to variables is unnecessary. Use them directly

  2. 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

Related Questions