【问题标题】:Rails 5, Devise, Omniauth, TwitterRails 5、设计、Omniauth、推特
【发布时间】:2016-11-03 07:01:13
【问题描述】:

我知道这个问题已经被问过很多次了,但我从来没有完全接受过答案。

所以我关注Ryan Bates' Railscast 关于这个话题,并将其与官方Devise Omniauth guide(基于FB)混合,但我只是没有让它像我期望的那样工作,所以我希望得到一些帮助.

我有一个Users::OmniauthCallbacksController,看起来像这样:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    @user = User.from_omniauth(request.env["omniauth.auth"])

    if @user.persisted?
      sign_in_and_redirect root_path, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
      flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
      redirect_to new_user_registration_url
    end
  end

  alias_method :twitter, :all

  def failure
    redirect_to root_path
  end
end

那我的User.rb也有两个方法

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.update(
        email: auth.info.email,
        password: Devise.friendly_token[0,20],
        username: auth.info.nickname,
        remote_avatar_url: auth.info.image,
        token: auth.credentials.token,
        secret: auth.credentials.secret
      )
    end
  end

  def self.new_with_session(params, session)
    super.tap do |user|
      if data = session["devise.twitter_data"]
        # user.attributes = params
        user.update(
          email: params[:email],
          password: Devise.friendly_token[0,20],
          username: data["info"]["nickname"],
          remote_avatar_url: data["info"]["image"],
          token: data["credentials"]["token"],
          secret: data["credentials"]["secret"]
        )
      end
    end
  end

我遇到了各种各样的问题。最直接的是因为我正在设置密码,用户在尝试登录时不知道密码(并且我不会在确认后自动登录)。

但是如果我不设置密码,它不会要求他们设置密码......所以这也有点奇怪。

这些是我在User 模型上的设计设置:

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :omniauthable, :omniauth_providers => [:twitter]

  validates :username,
    presence: true,
    uniqueness: {
      case_sensitive: false
    }

  validate :validate_username

  def validate_username
    if User.where(email: username).exists?
      errors.add(:username, :invalid)
    end
  end

所以我的问题是,当有人通过 Twitter 注册时,他们需要输入密码吗?无论如何,我都会自动将它们发送到registration/new.html.erb,因为 Twitter 不会返回电子邮件值。但我试图先让流程正常运行,然后再对其进行优化。

密码问题如何处理?

编辑 1

为了更清楚,我将不得不处理这个password_required 问题,无论 OAuth 提供者如何。

那么我如何覆盖所有 OAuth 提供者的要求?

【问题讨论】:

    标签: ruby-on-rails twitter devise omniauth ruby-on-rails-5


    【解决方案1】:

    您应该将the following method 添加到User 类中:

    def password_required?
      (provider.blank? || uid.blank?) && super
    end
    

    由于 Twitter 不返回用户的电子邮件,您可能还想tweak that email validation,但像您已经在做的那样将用户重定向到registration/new.html.erb 对我来说似乎是正确的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 2013-09-30
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 2015-11-28
      相关资源
      最近更新 更多