Rails Devise Twitter OAuth redirect to form to continue oAuth registration

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-12 01:47:43

问题


I have successfully implemented oAuth with omniauth-facebook and omniauth-google but I am having difficulties with implementing omniauth-twitter as it does not provide an email address.

I searched through available solutions on the Internet and one solution pointed out at removing Devise's email validation but email validation is needed for my app.

What I want instead is to redirect the user to a new form where the user only has to enter a new email address to complete his oAuth registration but I am not sure how to link it with the oAuth data to complete the registration as I am getting errors when I submit the form since username and password can't be blank from devise while only email is displayed in that form.

CallbackController

    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 contains the view where the user has to fill in his email address to complete registration.

User Model

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 signup form (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 %>

Even though the Twitter API recently allows applications to request additional permissions for their email, I am unsure of how to implement that.


回答1:


I finally managed to solve it this way.

After the user is redirected and if it's a new user, we will render a form TwitterForm for the user to input an email to complete the registration.

Next, the form will be submitted to a custom action that we specified, in my case I put it under UsersController that'll complete the sign up process using the Twitter session data and the email that the user inputted.

You can't put the action together inside the CallbacksController due to some issues with Devise which I am unsure as to why there's an error.

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

UsersController

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

User Model

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



回答2:


Try this solution, it'll be help you:

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



来源:https://stackoverflow.com/questions/39044670/rails-devise-twitter-oauth-redirect-to-form-to-continue-oauth-registration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!