仅当使用可验证的数据库时才检查用户是否对验证有效

Check if user is valid for authentication only if uses database authenticable

用户可以通过 OmniAuth 或电子邮件和密码登录我们的应用程序(但前提是他们受到邀请)。

我们有一个方法,检查用户是否可以通过电子邮件和密码登录,如下所示:

def active_for_authentication?
  super && valid_for_authentication
end

private
# Check wheter user was invited or not   
def valid_for_authentication
  User.invitation_accepted.find_by(id: id).present?
end

这很好用,但是当我想通过 OmniAuth 登录时,这种方法会阻止我。 如果使用OmniAuth认证,是否可以指定绕过此方法?

你可以在执行前检查下面的方法active_for_authentication?行

如果返回一些 res 数据,如果使用 omniauth 登录,下面的行将添加逻辑 unless res.present?

def logged_using_omniauth? request
  res = nil
  omniauth = request.env["omniauth.auth"]
  res = Authentication.find_by_provider_and_uid 
  (omniauth['provider'], omniauth['uid']) if omniauth
  res  
end

最后我换个方式想出来。 active_for_authentication?valid_for_authentication 已删除。

然后在app/models/user.rb我根据https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address#overwrite-devises-find_for_database_authentication-method-in-user-model

定义了下面的代码
  def self.find_for_database_authentication(warden_conditions)
    if valid_for_database_authentication?(warden_conditions)
      super
    else
      throw :warden, message: not_allowed_for_authentication
    end
  end

  # Check wheter user was invited or not
  private_class_method def self.valid_for_database_authentication?(params)
    User.invitation_accepted.find_by(params).present?
  end

  private_class_method def self.not_allowed_for_authentication
    I18n.t('devise.failure.user.not_allowed_for_authentication')
  end