获取(omniauth-facebook)和(omniauth-twitter)工作

Min*_*ohn 9 twitter facebook ruby-on-rails oauth omniauth

我正在使用:

  • Ruby on Rails 4
  • 设计3.0.3
  • omn​​iauth(1.1.4)
  • omn​​iauth-facebook(1.4.1)
  • omn​​iauth-twitter(1.0.0)

我最近设置了我的omniauth-facebook一切正常.现在我想添加omniauth-twitter但不知何故我搞砸了,非常糟糕.

1.)设置我的Omniauth-Facebook我这样做(简而言之):

gem 'omniauth'
gem 'omniauth-facebook'
Run Code Online (Sandbox Code Playgroud)

2.)在我的用户模型中添加了列" provider"和" uid".

3.)接下来,我在config/initializers/devise.rb中声明了提供程序:

require "omniauth-facebook"
config.omniauth :facebook, "App_ID", "App_Secret",
                                {:scope => 'email,offline_access',
                                 :client_options => {:ssl => {:ca_file => 'lib/assets/cacert.pem'}},
                                 :strategy_class => OmniAuth::Strategies::Facebook}
Run Code Online (Sandbox Code Playgroud)

4.)我编辑了Model User.rb

# Facebook Settings
def self.find_for_facebook_oauth(auth, signed_in_resource = nil)
    user = User.where(provider: auth.provider, uid: auth.uid).first
    if user.present?
        user
    else
        user = User.create(first_name:auth.extra.raw_info.first_name,
                                             last_name:auth.extra.raw_info.last_name,
                                             facebook_link:auth.extra.raw_info.link,
                                             user_name:auth.extra.raw_info.name,
                                             provider:auth.provider,
                                             uid:auth.uid,
                                             email:auth.info.email,
                                             password:Devise.friendly_token[0,20])
    end
end
Run Code Online (Sandbox Code Playgroud)

并添加了设计属性:

:omniauth_providers => [:facebook]
Run Code Online (Sandbox Code Playgroud)

5.)我编辑了路线:

devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
Run Code Online (Sandbox Code Playgroud)

结束

虽然这对Facebook来说非常有效,但我现在已经试了好几个小时才能让它适用于Twitter,我只是想弄明白.

如果有经验的人,或者只是知道解决方案可以帮我设置,我会非常感激:)

谢谢你们,对不起,长期的帖子.

此外

Twitter没有提供:电子邮件属性所以我必须拆分我的用户注册流程我猜?

我在我的用户模型中的Twitter操作

# Twitter Settings
def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth[:provider], :uid => auth[:uid]).first
    unless user
        user = User.create(:first_name => auth[:name],
                                             :user_name => auth[:screen_name],
                                             :provider => auth[:provider], :uid => auth[:uid],
                                             :password => Devise.friendly_token[0,20]
        )
    end
    user
end

# build auth cookie hash for twitter
def self.build_twitter_auth_cookie_hash data
    {
        :provider => data.provider, :uid => data.uid.to_i,
        :access_token => data.credentials.token, :access_secret => data.credentials.secret,
        :first_name => data.name, :user_name => data.screen_name,

    }
end
Run Code Online (Sandbox Code Playgroud)

我必须为用户迁移确认 - > 如何:添加:确认用户

我的表格的问题,(至少我现在开始这个poing :))

在此输入图像描述

Mat*_*ias 13

要解决您使用电子邮件的问题,您可以设置虚拟邮件,或添加用户添加其电子邮件的第二步.

虚拟邮件:

class User < ActiveRecord::Base

  before_create :set_dummy_mail, if self.provider == "twitter"

  private

  def set_dummy_mail
    self.email = "#{self.name}_email@example.com"
  end

end
Run Code Online (Sandbox Code Playgroud)

或者第二步选项:

如果提供程序是twitter且电子邮件为空,请修改您的控制器以重定向到添加电子邮件步骤.如果提供者是推特,也许您还必须修改您的验证以允许在创建时将电子邮件留空.

更新:我这样做如下:

的Gemfile:

gem "devise"
gem "omniauth"
gem "omniauth-facebook"
gem "omniauth-twitter"
Run Code Online (Sandbox Code Playgroud)

我用了:

  • 设计版本2.2.3
  • omn​​iauth 1.1.4
  • omn​​iauth-facebook 1.3.0
  • omn​​iauth-twitter 0.0.17

如果您使用的是不同的版本,您可能必须更改一些内容..

routes.rb中:

devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }

devise_scope :user do
  post "account/create" => "users/accounts#create"
end
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ user.rb

class User < ActiveRecord::Base

  # allow email blank for first create
  validates_format_of :email, :with => Devise.email_regexp, :allow_blank => true, :if => :email_changed?

  # facebook find method
  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(:first_name => auth.extra.raw_info.first_name, 
                         :last_name => auth.extra.raw_info.last_name, 
                         :facebook_link => auth.extra.raw_info.link, 
                         :user_name => auth.extra.raw_info.name
                         :provider => auth.provider, 
                         :uid => auth.uid, :email => auth.info.email, 
                         :password => Devise.friendly_token[0,20]
                        )
      user.confirm!
    end
    user
  end

  # twitter find method
  def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth[:provider], :uid => auth[:uid]).first
    unless user
      user = User.create(:first_name => auth[:first_name], :user_name => auth[:user_name],
                         :provider => auth[:provider], :uid => auth[:uid], 
                         :password => Devise.friendly_token[0,20]
                        )
    end
    user
  end

  # build auth cookie hash for twitter
  def self.build_twitter_auth_cookie_hash data
    {
      :provider => data.provider, :uid => data.uid.to_i,
      :access_token => data.credentials.token, :access_secret => data.credentials.secret,
      :first_name => data.screen_name, :user_name => data.name,

    }
  end

end
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/用户/ omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  # callback action for facebook auth
  def facebook
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  # callback action for twitter auth
  def twitter
    data = session["devise.omniauth_data"] = User.build_twitter_auth_cookie_hash(request.env["omniauth.auth"])

    user = User.find_for_twitter_oauth(data)
    if user.confirmed? # already registered, login automatically
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
      sign_in_and_redirect user, :event => :authentication
    elsif !user.email?
      flash[:error] = "You must add an email to complete your registration."
      @user = user
      render :add_email
    else
      flash[:notice] = "Please confirm your email first to continue."
      redirect_to new_user_confirmation_path
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

应用程序/视图/用户/ omniauth_callbacks/add_email.html.erb

<%= form_for(@user, :as => "user", :url => account_create_path, :html => {:class => "form-inline"}) do |f| %>
  <%= f.email_field :email, :placeholder => User.human_attribute_name(:email), :class => "input-medium" %>
  <%= f.submit "Finish registration", :class => "btn btn-small" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/用户/ accounts_controller.rb

class Users::AccountsController < ApplicationController

  def create
    data = session["devise.omniauth_data"]
    data[:email] = params[:user][:email]
    user = User.find_for_twitter_oauth(data)
    user.email = data[:email]

    if user.save
      flash[:notice] = I18n.t "devise.registrations.signed_up_but_unconfirmed"
      redirect_to root_path
    else
      flash[:error] = I18n.t "devise.omniauth_callbacks.failure", :kind => data[:provider].titleize, :reason => user.errors.full_messages.first
      render "users/omniauth_callbacks/add_email"
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

也许您必须修改我的解决方案的一个或其他部分.您还可以重构用户模型中的两个方法(find_for_facebook_auth,find_for_twitter_auth)以使用一个动态方法.如果你还有问题的话,试试看,让我知道.如果您发现任何拼写错误,请让我知道..此外,您应该编写测试来检查系统中的所有内容.