我已经使用 omniauth-facebook 和 omniauth-google 成功实现了oAuth,但是我在执行 omniauth-twitter ,因为它不提供电子邮件地址。
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.
我通过互联网上的可用解决方案进行了搜索,一个解决方案指出了删除Devise的电子邮件验证,但我的应用程序需要电子邮件验证。
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.
我想要的是将用户重定向到新的表单,用户只需输入一个新的电子邮件地址即可完成他的oAuth注册,但我不知道如何将它与oAuth数据链接到完成注册,因为我提交表单时收到错误,因为用户名和密码不能为空,而只有电子邮件以该表单显示。
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 endtwitter_register_path 包含视图,用户必须填写他的电子邮件地址才能完成注册。
twitter_register_path contains the view where the user has to fill in his email address to complete registration.
用户模型
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('','') end endTwitter注册表单(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最近允许应用程序为其电子邮件请求其他权限,我不确定如何实现。
推荐答案我终于设法以这种方式解决了。
I finally managed to solve it this way.
用户重定向后,如果是新用户,我们将为用户呈现一个表单 TwitterForm 输入一封电子邮件以完成注册。
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.
接下来,表单将提交给我们指定的自定义操作,在我的情况下,我把它放在 UsersController ,将使用Twitter会话数据和用户输入的电子邮件完成注册过程。
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.
您不能放由于Devise的一些问题,CallbacksController内部的动作一起出现,我不确定为什么会出现错误。
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.
设计回调控制器
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 endUsersController
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 endTwitterForm
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更多推荐
Rails Devise Twitter OAuth重定向到表单继续oAuth注册
发布评论