获取(omniauth-facebook)和(omniauth-twitter)工作 [英] Getting (omniauth-facebook) and (omniauth-twitter) work
问题描述
我正在使用:
- 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
/ pre>
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
也许你必须修改我的解决方案的一个或其他部分。你也可以重构用户模型中的两个方法(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屋!