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

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

问题描述



我正在使用:




  • Ruby on Rails 4

  • devise 3.0.3

  • omniauth(1.1.4)

  • omniauth-facebook(1.4.1)

  • omniauth-twitter(1.0.0)



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



1 。)要设置我的 Omniauth-Facebook 我做了这个(简而言之):

  gem'omniauth'
gem'omniauth-facebook'

2。)提供者 uid 列添加到我的



3。)接下来,我在配置/初始化程序/ devise.rb中声明了提供程序:

 需要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

 #Facebook设置
def self.find_for_facebook_oauth(auth,signed_in_resource = nil)
user = User.where(provider:auth.provider,uid:auth.uid).first
如果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,
密码:Devise.friendly_token [0,20])
end
end

并将属性添加到设计中:

 :omniauth_providers => [:facebook] 

5。)我编辑了路线: p>

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

THE END



尽管这对Facebook来说完美无暇,但我已经尝试了几个小时,以便让Twitter在Twitter上工作,我只是无法想像出来。



如果有人在这方面有经验,或者只是知道解决方案可以帮助我设定这个,我将非常感激:)



谢谢你们,对不起对于长的帖子。



另外



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



用户模型

中的 Twitter 操作

<$
user = User.where(:provider => auth [:provider],: uid => auth [:uid])。首先
除非用户
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
用户
结束

#为Twitter创建auth cookie哈希
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

我不得不迁移可确认的用户 - > 如何:添加:确认给用户



我的表单的问题,(至少现在可以得到这个poing :) :)



解决方案

要解决您的电子邮件问题,您只需设置一个虚拟邮件,或添加第二步,用户添加他/她的电子邮件。



虚拟邮件:

  class User< ActiveRecord :: Base 

before_create:set_dummy_mail,如果self.provider ==twitter

private

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

end

或第二步选项:



修改您的控制器以重定向到添加电子邮件步骤,如果提供者微博和电子邮件是空白的。也许你也必须修改你的验证,以允许电子邮件空白创建如果提供者是微博。



更新:我做到了如下:



Gemfile:

  gemdevise
gem omniauth
gemomniauth-facebook
gemomniauth-twitter

我使用:




  • 设计版本2.2.3

  • omniauth 1.1.4

  • omniauth-facebook 1.3.0

  • omniauth-twitter 0.0.17



如果您使用不同的版本,您可能必须更改几项。



routes.rb:

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

devise_scope:user do
postaccount / create=> users / accounts#create
end

app / models / user.rb



  class User< ActiveRecord :: Base 

#允许电子邮件空白首先创建
validates_format_of:email,:with => Devise.email_regexp,:allow_blank => true,if => :email_changed?

#facebook find方法
def self.find_for_facebook_oauth(auth,signed_in_resource = nil)
user = User.where(:provider => auth.provider,:uid => ; auth.uid).first
除非用户
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
用户
结束

#twitter find方法
def self.find_for_twitter_oauth(auth,signed_in_resource = nil)
user = User。 where(:provider => auth [:provider],:uid => auth [:uid])。first
除非用户
user = User.create(:first_name => auth [ first_name],:user_name => auth [:user_name],
:provider => auth [:provider],:uid => auth [:uid],
:password => .friendly_token [0,20]

end
用户
结束

#为Twitter创建auth cookie哈希
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

  class Users :: OmniauthCallbacksController< Devise :: OmniauthCallbacksController 

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

如果@ user.persisted?
sign_in_and_redirect @user,:event => :认证
set_flash_message(:notice,:success,:kind =>Facebook)if is_navigational_format?
else
会话[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)
如果user.confirmed? #已注册,自动登录
flash [:notice] = I18n.tdevise.omniauth_callbacks.success,:kind => Twitter
sign_in_and_redirect用户,:event => :身份验证
elsif!user.email?
flash [:error] =您必须添加电子邮件才能完成注册。
@user = user
render:add_email
else
flash [:notice] =请先确认您的电子邮件以继续。
redirect_to new_user_confirmation_path
end
end

end

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

 <%= form_for(@user, :as =>user,:url => account_create_path,:html => {:class =>form-inline})do | f | %GT; 
<%= f.email_field:email,:placeholder => User.human_attribute_name(:email),:class => input-medium%>
<%= f.submit完成注册,:class => btn btn-small%>
<%end%>

app / controllers / users / accounts_controller.rb

  class Users :: AccountsController< ApplicationController 

def create
data = session [devise.omniauth_data]
data [:email] = params [:user] [:email]
user =用户名为
redirect_to root_path
else
flash [:error] = I18n.tdevise.omniauth_callbacks.failure,:kind => data [:provider] .titleize,:reason => user.errors.full_messages.first
呈现users / omniauth_callbacks / add_email
end
end

end
/ pre>

也许你必须修改我的解决方案的一个或其他部分。你也可以重构用户模型中的两个方法(find_for_facebook_auth,find_for_twitter_auth)来工作用一种动态方法。尝试一下,让我知道,如果你还有问题。如果您发现任何错字,请同时告知我们。另外您还应该编写测试来检查系统中的所有内容。


Bare with me, this will be Long.

I'm Using:

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

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.) To set up my Omniauth-Facebook i did this (in a nutshell):

gem 'omniauth'
gem 'omniauth-facebook'

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

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.) 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.) I edited the routes:

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

THE END

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.

In Addition

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

My Twitter action in my User Model

# 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.

Dummy mail:

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

Or the second step option:

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.

UPDATE: I did it like following:

Gemfile:

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

I used:

  • devise version 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

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

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

<%= 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

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

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天全站免登陆