Rails 设计 Twitter OAuth 重定向到表单以继续 oAuth 注册

Rails Devise Twitter OAuth redirect to form to continue oAuth registration

我已经使用 omniauth-facebookomniauth-google 成功实施了 oAuth,但是我在实施 omniauth-twitter 时遇到了困难,因为它不提供电子邮件地址。

我在 Internet 上搜索了可用的解决方案,一个解决方案指出删除 Devise 的电子邮件验证,但我的应用程序需要电子邮件验证。

我想要的是将用户重定向到一个新表单,用户只需输入一个新的电子邮件地址即可完成他的 oAuth 注册,但我不确定如何 link 它与 oAuth数据来完成注册,因为我在提交表单时遇到错误,因为用户名和密码不能从设计中留空,而该表单中只显示电子邮件。

回调控制器

    def twitter
        @user = User.from_omniauth(request.env["omniauth.auth"])
        if @user.persisted?
          flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
          sign_in_and_redirect @user, :event => :authentication
        else
          session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
          redirect_to twitter_register_path 
        end
    end

twitter_register_path 包含用户必须填写其电子邮件地址才能完成注册的视图。

用户模型

def self.from_twitter_omniauth(auth,email)
   where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.email = email
      user.name = auth["info"]["name"]
      user.password = Devise.friendly_token[0,20]
      user.remote_poster_image_url = auth["info"]["image"].gsub('http://','https://')
    end
end

Twitter 注册表单 (twitter_register_path)

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :email, required: true,label: false %>
  </div>

  <div class="signup">
    <%= f.button :submit, "Sign up",:class =>"register-button" %>
  </div>
<% end %>

尽管 Twitter API 最近允许应用程序为其电子邮件请求额外的权限,但我不确定如何实现。

试试这个解决方案,它会对你有所帮助:

https://www.digitalocean.com/community/tutorials/how-to-configure-devise-and-omniauth-for-your-rails-application

我终于这样解决了。

用户被重定向后,如果是新用户,我们将呈现一个表单TwitterForm供用户输入电子邮件以完成注册。

接下来,表单将提交给我们指定的自定义操作,在我的例子中,我将其放在 UsersController 下,它将使用 Twitter 会话数据和发送的电子邮件完成注册过程用户输入。

由于 Devise 的某些问题,您不能将操作放在 CallbacksController 中,我不确定为什么会出现错误。

设计回调控制器

 def twitter
        auth = request.env["omniauth.auth"]
        @user = User.where(provider: auth.provider, uid: auth.uid).first_or_create
        if @user.persisted?
            flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
            sign_in_and_redirect @user, :event => :authentication
        else
            @form = TwitterForm.new 
            session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
            render :layout => 'none'
        end
    end

用户控制器

def twitter_register
    @form = TwitterForm.new(params[:twitter_form])
    if @form.valid?
      email = params[:twitter_form][:email]      
      @user = User.from_twitter_omniauth(session["devise.twitter_data"],email)
      if @user.persisted?
        flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
        sign_in_and_redirect @user, :event => :authentication
      else
        redirect_to register_path 
      end
    else 
      render 'callbacks/twitter',layout: 'none'
    end
  end

TwitterForm

class TwitterForm
  include ActiveModel::Model
  attr_accessor :email
  validates :email, presence: true,:format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
end

用户模型

def self.from_twitter_omniauth(auth,email)
   where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.email = email
      user.name = auth["info"]["name"]
      user.password = Devise.friendly_token[0,20]
      user.remote_poster_image_url = auth["info"]["image"]
    end
end