代码之家  ›  专栏  ›  技术社区  ›  TamerB

Deviate-Omniauth-如果之前已与提供商登录,则无法注册(电子邮件已存在)

  •  0
  • TamerB  · 技术社区  · 8 年前

    我正在使用designe和omniauth-*在Ruby on Rails应用程序上进行多供应商身份验证。

    一、 大部分都被跟踪了 this link 除了 omniauth_callbacks_controller.rb 我补充道:

    class OmniauthCallbacksController < Devise::OmniauthCallbacksController
        def after_sign_in_path_for(resource)
            if resource.email_verified?
                super resource
            else
                finish_signup_path(resource)
            end
        end
    
        def all
            puts request.env["omniauth.auth"]
            user = User.find_for_oauth(request.env["omniauth.auth"], current_user)
            if user.persisted?
                sign_in_and_redirect user, notice: "Signed in!"
            else
                session["devise.all"] = request.env["omniauth.auth"]
                redirect_to new_user_registration_url
            end
        end
        alias_method :twitter, :all
        alias_method :google_oauth2, :all
        alias_method :facebook, :all
        alias_method :instagram, :all
    end
    

    app/models/user.rb 我修改了 self.find_for_oauth 收件人:

    def self.find_for_oauth(auth, signed_in_resource = nil)
        identity = Identity.find_for_oauth(auth)
    
        user = signed_in_resource ? signed_in_resource :identity.user
        if user.nil?
            email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
            email = auth.info.email || if auth.info.nickname then auth.info.nickname + "@twitter.org" end
            user = User.where("email = ?", email).first if email
    
            if user.nil?
                user = User.new(
                    first_name: auth.extra.raw_info.name,
                    email: if auth.info.email != nil and auth.info.email != "" then auth.info.email else if auth.info.nickname then auth.info.nickname + "@twitter.org" end end ,
                    password: Devise.friendly_token[0, 20]
                )
                user.skip_confirmation!
                user.save!
            end
        end
    
        if identity.user != user
            identity.user = user
    
            identity.save!
        end
        user
    end
    

    通过创建 identity 模型,其中 user 有很多 identities

    然而,现在,我无法(使用电子邮件和密码)注册到 使用者 使用社交媒体创建的对象。

    我如何解决这个问题?

    使现代化

    我现在尝试的方法是检查用户之前是否已使用相同的电子邮件登录。如果是这样,应使用注册数据更新用户帐户,并提供更多信息 身份 对象具有 provider 设置为空白。

    更新2

    我现在可以通过自定义电子邮件和密码注册用户 create 中的方法 registrations_controller.rb 收件人:

    def create
        build_resource(sign_up_params)
    
        resource[:provider] = "<default provider>"
        if !User.find_by_email(resource.email) then
            resource.save
            yield resource if block_given?
            if resource.persisted?
                if resource.active_for_authentication?
                    set_flash_message! :notice, :signed_up
                    sign_up(resource_name, resource)
                    respond_with resource, location: after_sign_up_path_for(resource)
                else
                    set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
                    expire_data_after_sign_in!
                    respond_with resource, location: after_inactive_sign_up_path_for(resource)
                end
            else
                set_flash_message! :error, :"Something went wrong"
                clean_up_passwords resource
                set_minimum_password_length
                respond_with resource
            end
        else
            user = User.find_by_email(resource.email)
            if user.identities.count > 0 and user.provider != "<default provider>" then
            @identity = Identity.new
            @identity.provider = "made up provider"
            @identity.save
            user.password = resource.password
            if resource.country != nil and resource.country != "" then
                 user.country = resource.country
            end
            if resource.title != nil and resource.title != "" then
                if resource.title != nil and resource.title != "" then
                    user.title = resource.title
                end
                if resource.first_name != nil and resource.first_name != "" then
                    user.first_name = resource.first_name
                end
                if resource.last_name != nil and resource.last_name != "" then
                    user.last_name = resource.last_name
                end
                if resource.phone_number != nil and resource.phone_number != "" then
                    user.phone_number = resource.phone_number
                end
                if resource.country_code != nil and resource.country_code != "" then
                    user.country_code = resource.country_code
                end
                user.provider = "<default provider>"
    
                user.save
                yield user if block_given?
                if user.persisted?
                    if resource.active_for_authentication?
                        set_flash_message! :notice, :signed_up
                        respond_with resource, location: after_sign_up_path_for(resource)
                    else
                        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
                        expire_data_after_sign_in!
                        respond_with resource, location: after_inactive_sign_up_path_for(user)
                    end
                else
                set_flash_message! :error, :"Something went wrong"
                clean_up_passwords resource
                set_minimum_password_length
                respond_with resource
            end
        else
            set_flash_message! :error, "This Account already exists"
            redirect_to new_user_session_path
        end
    end
    

    但是,带有“确认邮件将发送到您的电子邮件”的消息,而实际上不会发送任何确认邮件。

    当用户第一次输入密码(用户使用电子邮件和密码注册)时,如何使其发送确认电子邮件?

    更新3

    我现在的问题是:

    使用Deviate,如何在第一次密码更新(或特定操作)时发送确认电子邮件(与注册确认电子邮件相同)?

    1 回复  |  直到 8 年前
        1
  •  0
  •   TamerB    8 年前

    我通过修改Deviate解决了注册和确认问题 registrations_controller.rb ,则, confirmations_controller.rb sessions_controller.rb

    在里面 registrations\u控制器。rb型 我修改了 create 方法:

    def create
        build_resource(sign_up_params)
    
        resource[:provider] = "<default provider>"
        if !User.find_by_email(resource.email) then
          resource.save
          yield resource if block_given?
          if resource.persisted?
            if resource.active_for_authentication?
              set_flash_message! :notice, :signed_up
              sign_up(resource_name, resource)
              respond_with resource, location: after_sign_up_path_for(resource)
            else
              set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
              expire_data_after_sign_in!
              respond_with resource, location: after_inactive_sign_up_path_for(resource)
            end
          else
            set_flash_message! :error, :"Something went wrong"
            clean_up_passwords resource
            set_minimum_password_length
            respond_with resource
          end
        else
          user = User.find_by_email(resource.email)
          if user.identities.count > 0 and (user.provider != "<default provider>" or user.provider != "<default provider>-confirmed") then
            @identity = Identity.new
            @identity.provider = "<default provider>"
            @identity.save
            user.password = resource.password
            if resource.username != nil and resource.username != "" then
                user.username = resource.username
            end
            if resource.phone_number != nil and resource.phone_number != "" then
                user.phone_number = resource.phone_number
            end
            ...
            user.provider = "<default provider>"
            user.save
            user.send_confirmation_instructions
            yield user if block_given?
            if user.persisted?
              if resource.active_for_authentication?
                set_flash_message! :notice, :signed_up
                respond_with resource, location: after_sign_up_path_for(resource)
              else
                set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
                expire_data_after_sign_in!
                respond_with resource, location: after_inactive_sign_up_path_for(user)
              end
            else
              set_flash_message! :error, :"Something went wrong"
              clean_up_passwords resource
              set_minimum_password_length
              respond_with resource
            end
          else
            set_flash_message! :error, "This Account already exists"
            redirect_to new_user_session_path
          end
        end
    end
    

    在里面 确认\控制器。rb型 我修改了 创造 show 方法:

    # POST /resource/confirmation
    def create
      self.resource = resource_class.send_confirmation_instructions(resource_params)
      yield resource if block_given?
    
      if successfully_sent?(resource)
        respond_with({}, location: after_resending_confirmation_instructions_path_for(resource_name))
      else
        if User.find_by_email(resource.email).provider != "<default provider>-confirmed" then
         User.find_by_email(resource.email).send_confirmation_instructions
         respond_with({}, location: after_resending_confirmation_instructions_path_for(resource_name))
        else
          respond_with(resource)
        end
      end
    end
    
    # GET /resource/confirmation?confirmation_token=abcdef
    def show
      self.resource = resource_class.confirm_by_token(params[:confirmation_token])
      yield resource if block_given?
    
      if resource.errors.empty?
        resource.provider = "<default provider>-confirmed"
        resource.save
        set_flash_message!(:notice, :confirmed)
        respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
      else
        if User.find_by_email(resource.email).provider != "<default provider>-confirmed" then
          a = User.find_by_email(resource.email)
          a.provider = "<defualt provider>-confirmed"
          a.save
          set_flash_message!(:notice, :confirmed)
          respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
        else
          respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
        end
      end
    end
    

    在里面 sessions\u控制器。rb型 我还修改了 创造 方法:

    def create
        self.resource = warden.authenticate!(auth_options)
        if User.find_by_email(resource.email) and User.find_by_email(resource.email).provider == "<default provier>-confirmed" then
          self.resource = warden.authenticate!(auth_options)
          set_flash_message!(:notice, :signed_in)
          sign_in(resource_name, resource)
          yield resource if block_given?
          respond_with resource, location: after_sign_in_path_for(resource)
        else
          signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
          set_flash_message!(:error, "You have not yet confirmed your email");
          redirect_to root_path
        end
    end