获得 (omniauth-facebook) 和 (omniauth-twitter) 工作 [英] Getting (omniauth-facebook) and (omniauth-twitter) work

查看:26
本文介绍了获得 (omniauth-facebook) 和 (omniauth-twitter) 工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用:

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

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

I recently set up my omniauth-facebook and everything works fine. Now i want to add omniauth-twitter but somehow i mess things up, pretty bad.

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

1.) To set up my Omniauth-Facebook i did this (in a nutshell):

gem 'omniauth'
gem 'omniauth-facebook'

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

2.) Added the columns "provider" and "uid" to my User model.

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

3.) Next, i declared the provider in my 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}

4.) 我编辑了我的模型 User.rb

4.) I edited my 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

并添加了要设计的属性:

and added the attributes to devise:

:omniauth_providers => [:facebook]

5.) 我编辑了路线:

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

结束

虽然这对 Facebook 非常有效,但我现在尝试了几个小时才能让它在 Twitter 上工作,但我无法弄清楚.

Although this worked perfectly for Facebook, i tried for hours now to get this working for Twitter, and i just cant figure it out.

如果有人在这方面有经验或知道解决方案可以帮助我进行设置,我将非常感激:)

If someone, who has experience in this, or just knows the solution could help me set this up, i would be very thankful :)

谢谢你们,很抱歉发了这么长的帖子.

Thank you guys, and sorry for the long Post.

另外

Twitter 不提供 :email 属性,所以我猜我必须拆分我的用户注册过程?

Twitter does not provide an :email Attribute so i have to Split up my User Registration Process i guess ?

我的用户模型中的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

我必须为用户迁移一个可确认的 -> 如何:向用户添加:可确认

I had to migrate a confirmable for Users -> How To: Add :confirmable to Users

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

My Form's Problem, (At Least im getting to this poing now :) )

推荐答案

要解决电子邮件问题,您可以只设置一个虚拟邮件,或者添加第二个步骤,让用户添加他/她的电子邮件.

To fix your problem with the email you could just set a dummy mail, or add a second step where the user adds his/her email.

虚拟邮件:

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

或者第二步选项:

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

Modify your controller to redirect to an add email step if the provider is twitter and the email is blank. Maybe you also have to modify your validations to allow email blank on create if the provider is twitter.

更新:我是这样做的:

宝石文件:

gem "devise"
gem "omniauth"
gem "omniauth-facebook"
gem "omniauth-twitter"

我用过:

  • 设计版本 2.2.3
  • omniauth 1.1.4
  • omniauth-facebook 1.3.0
  • omniauth-twitter 0.0.17

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

If you are using different versions, you maybe must change a few things..

routes.rb:

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

devise_scope :user do
  post "account/create" => "users/accounts#create"
end

app/models/user.rb

app/models/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

app/controllers/users/omniauth_callbacks_controller.rb

app/controllers/users/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

app/views/users/omniauth_callbacks/add_email.html.erb

app/views/users/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 %>

app/controllers/users/accounts_controller.rb

app/controllers/users/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

也许您必须修改我的解决方案的一部分或其他部分..您也可以重构用户模型中的两种方法(find_for_facebook_auth、find_for_twitter_auth)以使用一种动态方法.尝试一下,如果您仍有问题,请告诉我.如果您发现任何错别字,也请告诉我.另外,您应该编写测试来检查系统中的所有内容.

Maybe you have to modify the one or other part of my solution..you also could refactor the two methods in the user model (find_for_facebook_auth, find_for_twitter_auth) to work with one dynamic method. Try it out and let me know, if you still have problems. If you find any typo, please also let me know.. Also you should write tests to check everything within your system.

这篇关于获得 (omniauth-facebook) 和 (omniauth-twitter) 工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆