我有两个用户注册选项,
我后来在Twitter上注册了。有一些现有的用户注册电子邮件,我如何允许这些现有用户链接他们的twitter帐户,以便他们可以通过电子邮件或Twitter登录?
谢谢!
用户表:
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
endomniauth_callbacks_controller
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
endregistration_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发布于 2018-02-03 17:08:40
您应该更多地了解您的模型和数据库,但是通常的方法是:
您有一个身份模型,其中包含以下信息:
表标识:
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按钮订阅或登录时,您可以在identities表中搜索他,以查看您是否已经拥有它(您按提供者和uid进行搜索)。
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def twitter
callback(:twitter)
end
def facebook
callback(:facebook)
end
def google
callback(:google)
end
def callback(provider)
@user = User.find_for_oauth(request.env["omniauth.auth"], current_user)
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:success, :success, kind: "#{provider}".capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end用户模型
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
endhttps://stackoverflow.com/questions/48599621
复制相似问题