Ruby on rails 将现有设计用户(电子邮件注册)与Omniauth Twitter链接
我有2个用户注册选项Ruby on rails 将现有设计用户(电子邮件注册)与Omniauth Twitter链接,ruby-on-rails,ruby,devise,ruby-on-rails-5,omniauth,Ruby On Rails,Ruby,Devise,Ruby On Rails 5,Omniauth,我有2个用户注册选项 设计电子邮件注册 Omniauth Twitter注册 我后来加入了Twitter注册。有一些现有用户使用电子邮件注册,我如何允许这些现有用户链接他们的Twitter帐户,以便他们可以通过电子邮件或Twitter登录 谢谢大家! 用户表: create_table "designers", force: :cascade do |t| t.string "fullname" t.string "website" t.string "bio"
create_table "designers", force: :cascade do |t|
t.string "fullname"
t.string "website"
t.string "bio"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "avatar"
t.string "slug"
t.string "twitter"
t.string "email", default: "", null: false
t.string "username"
t.string "location"
t.boolean "featured", default: false
t.string "twitter_username"
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.boolean "is_admin", default: false
t.string "provider"
t.string "uid"
t.index ["email"], name: "index_designers_on_email"
t.index ["reset_password_token"], name: "index_designers_on_reset_password_token", unique: true
end
omniauth\u回调\u控制器
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
designer = Designer.from_omniauth(request.env['omniauth.auth'])
if designer.persisted?
sign_in_and_redirect designer, notice: "Signed in!"
else
session["devise.designer_attributes"] = designer.attributes
redirect_to new_designer_registration_url
end
end
alias_method :twitter, :all
end
class OmniAuthCallbackController
注册\u controller.rb
class RegistrationsController < Devise::RegistrationsController
def sign_up_params
params.require(:designer).permit(:username, :fullname, :email, :password, :password_confirmation)
end
def account_update_params
params.require(:designer).permit(:username, :fullname, :email, :location, :website, :twitter, :bio, :featured, :is_admin, :password, :password_confirmation, :current_password)
end
protected
def after_sign_up_path_for(resource)
edit_designer_path(current_designer) if current_designer
end
end
类注册控制器
您应该详细介绍一下您的模型和数据库,但通常的做法是:
您有一个标识模型,其中包含以下信息:
表标识:
id serial NOT NULL
user_id integer, # The user in your Users table
provider text, # Linkedin, Twitter, Yahoo, any other provider
uid text, # Other data provided by the Oauth provider....
email text,
name text,
token text,
profile_url text,
image_url text,
secret text,
CONSTRAINT identities_pk PRIMARY KEY (id)
当您的用户使用Twitter按钮订阅或登录时,您可以在Identifications表中搜索他,以查看您是否已经拥有它(您可以按提供者和uid进行搜索)
身份模型
class Identity < ApplicationRecord
belongs_to :user
validates_presence_of :uid, :provider
validates_uniqueness_of :uid, :scope => :provider
def self.find_for_oauth(auth)
identity = find_or_create_by(uid: "nickname: " + auth.uid, provider: auth.provider) # Same as User.rb (in find_for_oauth)
identity.name = auth.extra.raw_info.name
identity.email = auth.info.email
identity.image_url = auth.info.image
identity.profile_url = nil
identity.token = auth.credentials.token
identity.secret = auth.credentials.secret
identity.save
identity
end
end
类标识:provider的唯一性
定义self.find_for_oauth(auth)
identity=find_或create_by(uid:“昵称:+auth.uid,提供程序:auth.provider)#与User.rb相同(在find_for_oauth中)
identity.name=auth.extra.raw\u info.name
identity.email=auth.info.email
identity.image\u url=auth.info.image
identity.profile_url=nil
identity.token=auth.credentials.token
identity.secret=auth.credentials.secret
identity.save
身份
结束
结束
def self.find_for_oauth(auth, signed_in_resource = nil)
# Get the identity or create it if it does not exist
identity = Identity.find_for_oauth(auth)
user = signed_in_resource ? signed_in_resource : identity.user
# Create the user if needed (if no logged in user and the identity has no user associated)
if user.nil?
# Get the existing user by email if the provider gives us an email.
# If no email was provided we assign a temporary email and ask the
# user to verify it on the next step via UsersController.finish_signup
# email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
email = auth.info.email
user = User.find_by(:email => email) if email
email ||= "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com"
username = auth.info.nickname ? auth.info.nickname :
( auth.extra.raw_info.nickname ? auth.extra.raw_info.nickname :
( auth.extra.raw_info.username ? auth.extra.raw_info.username : "nickname: " + auth.uid) ) # Same as Identity.rb (in find_for_oauth)
new_username = username
# Create the user if it's a new registration.
# Use default values that will be updated later
if user.nil?
# Control if username is taken
user_same_name = User.find_by(:username => new_username)
while user_same_name
rnd = SecureRandom.random_number(10000).to_s
new_username = username + " (" + rnd + ")"
user_same_name = User.find_by(:username => new_username)
end
user = User.new(
name: auth.extra.raw_info.name,
username: new_username,
email: email,
password: Devise.friendly_token[0,20],
)
user.skip_confirmation!
user.save!
end
end
# Associate the identity with the user if needed
if identity.user != user
identity.user = user
identity.save!
end
user
end
class Identity < ApplicationRecord
belongs_to :user
validates_presence_of :uid, :provider
validates_uniqueness_of :uid, :scope => :provider
def self.find_for_oauth(auth)
identity = find_or_create_by(uid: "nickname: " + auth.uid, provider: auth.provider) # Same as User.rb (in find_for_oauth)
identity.name = auth.extra.raw_info.name
identity.email = auth.info.email
identity.image_url = auth.info.image
identity.profile_url = nil
identity.token = auth.credentials.token
identity.secret = auth.credentials.secret
identity.save
identity
end
end