首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将现有的设计用户(电子邮件注册)与Omniauth-Twitter连接起来

将现有的设计用户(电子邮件注册)与Omniauth-Twitter连接起来
EN

Stack Overflow用户
提问于 2018-02-03 16:43:40
回答 1查看 513关注 0票数 3

我有两个用户注册选项,

  1. 设计电子邮件注册
  2. Omniauth-Twitter注册

我后来在Twitter上注册了。有一些现有的用户注册电子邮件,我如何允许这些现有用户链接他们的twitter帐户,以便他们可以通过电子邮件或Twitter登录?

谢谢!

用户表:

代码语言:javascript
复制
  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_callbacks_controller

代码语言:javascript
复制
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

registration_controller.rb

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2018-02-03 17:08:40

您应该更多地了解您的模型和数据库,但是通常的方法是:

您有一个身份模型,其中包含以下信息:

表标识:

代码语言:javascript
复制
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进行搜索)。

代码语言:javascript
复制
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

用户模型

代码语言:javascript
复制
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

身份模型

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48599621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档