Connect Twitter Account to existing Devise Account

前端 未结 1 1819
余生分开走
余生分开走 2020-12-08 12:16

A user can register through Devise.

After the registration a User should be able to connect his

  • Twitter Account
<
相关标签:
1条回答
  • 2020-12-08 12:48

    gems

    gem 'omniauth-twitter'
    gem 'omniauth-facebook'
    gem 'omniauth-linkedin'
    

    in views

    <%= check_connection('Facebook')%>
    <%= check_connection('Linkedin')%>
    <%= check_connection('Twitter')%>
    

    helpers

      def check_connection(provider)
        if current_user.has_connection_with(provider)
          html = link_to disconnect_path(social: provider.downcase), class: "#{provider}-m phone-verified row" do
            content_tag :span, 'Verified', class: "verified"
          end
        else
          html = link_to user_omniauth_authorize_path(provider: provider.downcase), class: "#{provider}-m phone-verified row" do
            content_tag :span, 'Click to verify', class: "un-verified"
          end
        end
      end
    

    in user model - for you this might be different

      devise :database_authenticatable, :registerable, :confirmable, :lockable,
             :recoverable, :rememberable, :trackable, :validatable, :omniauthable,
             :omniauth_providers => [:facebook, :twitter, :linkedin]
    
      has_many :authorizations, :dependent => :destroy
    
      def has_connection_with(provider)
        auth = self.authorizations.where(provider: provider).first
        if auth.present?
          auth.token.present?
        else
          false
        end
      end
    

    in routes I have

      devise_for :users, :controllers => {:registrations => "users/registrations",
        :sessions => "users/sessions",
        :passwords => "users/passwords",
        :omniauth_callbacks => "users/omniauth_callbacks" #<- this one you need
      }
    

    create authorization table - see this link uninitialized constant User::Authorization | omniauth

    class CreateAuthorizations < ActiveRecord::Migration
      def change
        create_table :authorizations do |t|
          t.string :provider
          t.string :uid
          t.integer :user_id
          t.string :token
          t.string :secret
          t.string :first_name
          t.string :last_name
          t.string :name
          t.string :link
    
          t.timestamps
        end
      end
    end
    

    OmniauthCallbacksController /controllers/users/...

    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      require 'uuidtools'
    
      def facebook
        oauthorize "Facebook"
      end
    
      def twitter
        oauthorize "Twitter"
      end
    
      def linkedin
        oauthorize "LinkedIn"
      end
    
      def passthru
        render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
      end
    
    private
    
      def oauthorize(kind)
        @user = find_for_ouath(kind, env["omniauth.auth"], current_user)
        if @user
          flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => kind
          session["devise.#{kind.downcase}_data"] = env["omniauth.auth"]
          sign_in_and_redirect @user, :event => :authentication
        end
      end
    
      def find_for_ouath(provider, access_token, resource=nil)
        user, email, name, uid, auth_attr = nil, nil, nil, {}
        case provider
          when "Facebook"
            uid = access_token['uid']
            email = access_token['info']['email']
            auth_attr = { :uid => uid, :token => access_token['credentials']['token'],
              :secret => nil, :first_name => access_token['info']['first_name'],
              :last_name => access_token['info']['last_name'], :name => access_token['info']['name'],
              :link => access_token['extra']['raw_info']['link'] }
          when "Twitter"
            uid = access_token['extra']['raw_info']['id']
            name = access_token['extra']['raw_info']['name']
            auth_attr = { :uid => uid, :token => access_token['credentials']['token'],
              :secret => access_token['credentials']['secret'], :first_name => access_token['info']['first_name'],
              :last_name => access_token['info']['last_name'], :name => name,
              :link => "http://twitter.com/#{name}" }
          when 'LinkedIn'
            uid = access_token['uid']
            name = access_token['info']['name']
            auth_attr = { :uid => uid, :token => access_token['credentials']['token'],
              :secret => access_token['credentials']['secret'], :first_name => access_token['info']['first_name'],
              :last_name => access_token['info']['last_name'],
              :link => access_token['info']['public_profile_url'] }
        else
          raise 'Provider #{provider} not handled'
        end
        if resource.nil?
          if email
            user = find_for_oauth_by_email(email, resource)
          elsif uid && name
            user = find_for_oauth_by_uid(uid, resource)
            if user.nil?
              user = find_for_oauth_by_name(name, resource)
            end
          end
        else
          user = resource
        end
    
        auth = user.authorizations.find_by_provider(provider)
        if auth.nil?
          auth = user.authorizations.build(:provider => provider)
          user.authorizations << auth
        end
        auth.update_attributes auth_attr
    
        return user
      end
    
      def find_for_oauth_by_uid(uid, resource=nil)
        user = nil
        if auth = Authorization.find_by_uid(uid.to_s)
          user = auth.user
        end
        return user
      end
    
      def find_for_oauth_by_email(email, resource=nil)
        if user = User.find_by_email(email)
          user
        else
          user = User.new(:email => email, :password => Devise.friendly_token[0,20])
          user.save
        end
        return user
      end
    
      def find_for_oauth_by_name(name, resource=nil)
        if user = User.find_by_name(name)
          user
        else
          first_name = name
          last_name = name
          user = User.new(:first_name => first_name, :last_name => last_name, :password => Devise.friendly_token[0,20], :email => "#{UUIDTools::UUID.random_create}@host")
          user.save(:validate => false)
        end
        return user
      end
    
    end
    
    0 讨论(0)
提交回复
热议问题