用户可以通过Devise注册.
> Twitter帐户
在过去,我使用omniauth让facebook和twitter连接工作.但在这种特殊情况下,我需要将Twitter帐户链接到现有的设备帐户.
任何人都可以帮助我从哪里开始或阅读,我完全无能为力.
解决方法@H_502_12@
宝石
gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-linkedin'
在视图中
<%= check_connection('Facebook')%>
<%= check_connection('Linkedin')%>
<%= check_connection('Twitter')%>
助手
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),'Click to verify',class: "un-verified"
end
end
end
在用户模型中 – 对你而言,这可能会有所不同
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
在我的路线
devise_for :users,:controllers => {:registrations => "users/registrations",:sessions => "users/sessions",:passwords => "users/passwords",:omniauth_callbacks => "users/omniauth_callbacks" #<- this one you need
}
创建授权表 – 请参阅此链接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,{}
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,:secret => access_token['credentials']['secret'],:name => name,:link => "http://twitter.com/#{name}" }
when 'LinkedIn'
uid = access_token['uid']
name = access_token['info']['name']
auth_attr = { :uid => uid,: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,20],:email => "#{UUIDTools::UUID.random_create}@host")
user.save(:validate => false)
end
return user
end
end
gem 'omniauth-twitter' gem 'omniauth-facebook' gem 'omniauth-linkedin'
在视图中
<%= check_connection('Facebook')%> <%= check_connection('Linkedin')%> <%= check_connection('Twitter')%>
助手
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),'Click to verify',class: "un-verified" end end end
在用户模型中 – 对你而言,这可能会有所不同
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
在我的路线
devise_for :users,:controllers => {:registrations => "users/registrations",:sessions => "users/sessions",:passwords => "users/passwords",:omniauth_callbacks => "users/omniauth_callbacks" #<- this one you need }
创建授权表 – 请参阅此链接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,{} 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,:secret => access_token['credentials']['secret'],:name => name,:link => "http://twitter.com/#{name}" } when 'LinkedIn' uid = access_token['uid'] name = access_token['info']['name'] auth_attr = { :uid => uid,: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,20],:email => "#{UUIDTools::UUID.random_create}@host") user.save(:validate => false) end return user end end