2

So I've got Omniauth with Twitter validation functioning at about 95%, in other-words it's almost fully functional. When clicking the | Sign-In with Twitter | button on my app, it re-directs me to twitter where I am then prompted to enter my Twitter credentials, and then re-directed back to the app.

However, instead of logging me in after the Twitter auth process I get the following error on the Sign-in page:

1 error prohibited this user from being saved:

    Email can't be blank

How can I get Omniauth to re-direct me to the logged in page in my case the /posts page? And why is it producing such an error, when Omniauth is supposed to authorize me via Twitter validation?

User model:

class User < ActiveRecord::Base
  has_many :authentications

  # Include default devise modules. Others available are:
  # :token_authenticatable, :lockable, :timeoutable and :activatable
  devise :database_authenticatable, :registerable, 
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation
  # attr_accessible :title, :body

  def apply_omniauth(omniauth)
    self.email = omniauth['info']['email'] if email.blank?
    authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'])

  end

  def password_required?
    (authentications.empty? || !password.blank?) && super
  end


end

Authentications Controller:

class AuthenticationsController < ApplicationController
  def create
    omniauth = request.env["omniauth.auth"]
    authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
    if authentication
      flash[:notice] = "Signed in successfully."
      sign_in_and_redirect(:user, authentication.user)
    elsif current_user
      current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
      flash[:notice] = "Authentication successful."
      redirect_to authentications_url
    else
      user = User.new
      user.apply_omniauth(omniauth)
      if user.save
        flash[:notice] = "Signed in successfully."
        sign_in_and_redirect(:user, user)
      else
        session[:omniauth] = omniauth.except('extra')
        redirect_to new_user_registration_url
      end
    end
  end
end

Registrations Controller:

class RegistrationsController < Devise::RegistrationsController
  def create
    super
    session[:omniauth] = nil unless @user.new_record?
  end

  private

  def build_resource(*args)
    super
    if session[:omniauth]
      @user.apply_omniauth(session[:omniauth])
      @user.valid?
    end
  end
end
  • omniauth is first trying to create a user on callback, in your User model you have `validate_presence_of :email`, so perhaps you are not assigning an email after the initial omniauth process? – gmaliar Feb 28 '13 at 20:32
  • @Guy Thanks for your response, would you care to elaborate? I've added my user.rb file to the op for good measure, please let me know if there are any other files I should add to help solve this! –  Feb 28 '13 at 20:33
  • Can you show the controller as well ? – gmaliar Feb 28 '13 at 20:37
  • Sure, i've updated the op with them. –  Feb 28 '13 at 20:41

1 Answers1

1

I just remembered, the reason is actually simple, twitter doesn't return email in the omniauth request so it redirects you to the new user registration page and you have to fill in your email.

https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema

furthermore this could be of help

Skip email validation for omniauth-twitter on devise 2.0

Community
  • 1
  • 1
gmaliar
  • 5,294
  • 1
  • 28
  • 36
  • That makes sense, strangely enough when following @DanStark 's answer on the http://stackoverflow.com/questions/10226203/skip-email-validation-for-omniauth-twitter-on-devise-2-0 post i am getting the following error: undefined local variable or method `provider' for # not sure why the provider line isn't being recognized. –  Feb 28 '13 at 20:55
  • it's not part of the User model – gmaliar Feb 28 '13 at 21:00