在 Devise 中使登录失败,以便显示默认错误消息

问题描述 投票:0回答:1

使用轨道和设计。在下面的代码中,我检查用户是否已经使用omniauth登录(使用

email
provider
字段进行检查)。如果是,那么我想通过默认消息来失败。虽然以下代码有效,但我手动调用
devise.failure.invalid
消息,我不喜欢这样做。

我想调用 Devise 中的一些现有方法,以便它可以模拟失败的登录,这样我就不必重新定义东西。

class Users::SessionsController < Devise::SessionsController
  before_action :check_omniauth_presence, only: [:create]

  private
  
    def check_omniauth_presence
      resource = resource_class.where(email: params[resource_name][:email]).where.not(provider: nil)

      if resource.present?
        auth_keys = resource_class.authentication_keys.first.to_s
        flash[:alert] = t("devise.failure.invalid", authentication_keys: auth_keys)
        redirect_to new_session_path(resource_name)
      end
    end
end

在这里你可以看到我重新定义了

authentication_keys
,手动调用翻译。我尝试了
set_flash_message
(但仍然是手动)和
warden.authenticate!(nil)
,但没有成功。

ruby-on-rails devise
1个回答
0
投票

您可以利用 Devise 在幕后使用的 Warden 内置故障机制。

warden
对象有一个
fail!
方法,该方法采用符号来表示失败原因,并且在调用时将停止请求周期并直接进入失败应用程序(即您的设计失败应用程序)。

Devise 的故障应用程序将使用此符号为您设置适当的闪烁消息。以下是您如何重构代码以利用它:

class Users::SessionsController < Devise::SessionsController
  prepend_before_action :check_omniauth_presence, only: [:create]

  private
  
  def check_omniauth_presence
    resource = resource_class.where(email: params[resource_name][:email]).where.not(provider: nil)

    if resource.present?
      # Fail the authentication using Warden's built-in mechanism
      warden.custom_failure!
      throw(:warden, reason: :invalid)
    end
  end
end

以下是我们所做工作的详细说明:

  1. prepend_before_action
    :我们使用
    before_action
    来代替
    prepend_before_action
    ,以确保我们的方法在堆栈中的任何其他方法之前被调用。

  2. warden.custom_failure!
    :告诉 Warden 存在自定义失败,因此不应继续使用默认身份验证策略。

  3. throw(:warden, reason: :invalid)
    :这是对Warden失败机制的实际调用。它抛出一个符号 (
    :warden
    ),Warden 中间件会捕获该符号。
    reason: :invalid
    部分通知失败应用程序身份验证失败的原因,然后使用它来设置适当的闪存消息。

使用这种方法,您不再需要手动设置闪现消息或处理重定向,因为 Devise 故障应用程序将为您处理这些事情。

© www.soinside.com 2019 - 2024. All rights reserved.