Omniauth-devise error: "Validation error: email has already been accepted"

I am trying to create a rails 4 application with omniauth devise:

  • signin with facebook
  • signin with google
  • signin with linkedin
  • twitter signin

Here I can log in using either facebook, linkedin, twitter or google. But my problem: my Google email address and the associated email address are the same. And login with google and then login with linkedin gives me this error:

"Validation failed: Email has already been taken"

This is a problem because devise uses :unique => truein the migration file for the email field.

Can someone give me a good idea to handle this error?

+3
source share
2 answers

I followed these steps and worked fine for me:

1. Gemfile

gem 'omniauth-facebook', '1.4.0'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'

2. /route.rb

devise_for :users, controllers: { omniauth_callbacks: "omniauth_callbacks" }

3.

<%= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) %>
<%= link_to "Sign in with twitter", user_omniauth_authorize_path(:twitter) %>
<%= link_to "Sign in with google", user_omniauth_authorize_path(:google_oauth2) %>

4. /omniauth _callbacks_controller.rb

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  skip_before_filter :authenticate_user!

  def all
    user = User.from_omniauth(request.env["omniauth.auth"], current_user)
    if user.persisted?
            flash[:notice] = "you are successfully logged in!!"
            sign_in_and_redirect(user)
        else
            session["devise.user_attributes"] = user.attributes
            redirect_to new_user_registration_url
        end
  end

  def failure
    super
  end

  alias_method :facebook, :all
  alias_method :twitter, :all
  alias_method :google_oauth2, :all
end

5.

rails g migration add_social_network_info_columns_to_users name image_url locations

# generate new model Authorization
rails g model Authorization user_id:integer provider uid token secret username

6. /User.rb

class User < ActiveRecord::Base


require 'securerandom'

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

  has_many :authorizations

  # omniauth facebook provider
  def self.from_omniauth(auth, current_user)
    # check for existing authorization
    # Find or create Authorization with: provider, uid, token and secret
    authorization = Authorization.where(
      :provider => auth.provider, 
      :uid => auth.uid.to_s, 
      :token => auth.credentials.token, 
      :secret => auth.credentials.secret
    ).first_or_initialize

    if authorization.user.blank?
      user = current_user.nil? ? User.where('email = ?', auth["info"]["email"]).first : current_user

      # save user related data in user table
      if user.blank?
        User.new(
          :email            => auth.info.email,
          :password         => Devise.friendly_token[0,10],
          :name             => auth.info.name,
          :locations        => auth.info.location,
          :image_url        => auth.info.image
        )
        # since twitter don't provide email, 
        # so you need to skip validation for twitter.
        auth.provider == "twitter" ?  user.save!(:validate => false) :  user.save!
      end

      # store authorization related data in authorization table
      authorization.username = auth.info.nickname
      authorization.user_id = user.id
      authorization.save!
    end
    authorization.user
  end
end

6. /Authorization.rb

class Authorization < ActiveRecord::Base
  belongs_to :user
end

: https://github.com/mohitjain/social-login-in-rails

+1

, , , , 1 ( , ). !

, - :

https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

, , , .

, , _Many Identities. Identity , , , . , (, Facebook...). :

http://railscasts.com/episodes/235-omniauth-part-1?view=asciicast

http://railscasts.com/episodes/236-omniauth-part-2?view=asciicast

has_many Identities, .

, , , :

if @user.errors.added?(:email, :taken)
  # do whatever you want - e.g. one of the 4 options below.
end

, :

  • , , .

  • , , ( ), / , .

  • , ( ), , . , (, , , , ), , ( ).

  • , , . , , , , .

1 , , , , , , - , - , , , . , , - (, 2, 3 4). , , , , - , Facebook , , ( . ). , ( ), , , .

2 , , , devise; . , , . (, , , , , -, ).

3 , . .

4 , .

2, , 1 . , 4 (, , , 1 ).

2, 3 4 - , 1, , , , , , . !

:

https://github.com/intridea/omniauth/wiki/Managing-Multiple-Providers

- , , , , " , , ", , .

, , , - , Facebook, ( , ), , Facebook, . , , , , linkedin, Facebook (, , ). , , Facebook, ( ), , Facebook. , , " ", 2 , , ...

, , twitter , , twitter linkedin, . , , Facebook ( ), Facebook. , , , , , ! , !

+3

All Articles