轨道 - 如何在用户登录时重写设计 SessionsController 以执行特定任务


使用 Devise

管理用户会话/注册 每次用户登录时,以及他被 Devise 重定向到连接用户的主页之前,我需要执行特定任务(例如,更新此特定用户的用户表中的某些字段)。

我是否必须覆盖设计会话控制器,如果是,如何?

或者,您可以创建自己的会话控制器

class SessionsController < Devise::SessionsController
  def new
    super
  end
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    if !session[:return_to].blank?
      redirect_to session[:return_to]
      session[:return_to] = nil
    else
      respond_with resource, :location => after_sign_in_path_for(resource)
    end
  end
end

并在routes.rb中添加:

devise_for :users, controllers: {sessions: "sessions"}

如果你看一下 Devise 的 sessions_controller#create 实现,你会注意到如果你传递一个块,它们就会产生。

因此,只需对它们的会话控制器进行子类化,并在调用 super 时传递一个块。为此,首先告诉 Devise in routes.rb您想使用自己的会话控制器:

devise_for :users, controllers: { sessions: 'users/sessions' }

然后创建一个SessionsController类,并在创建方法中调用 super 时传递一个块。它看起来像这样:

# app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  layout "application"
  
  # POST /login
  def create
    super do |user|
      if user.persisted?
        user.update(foo: :bar)
      end
    end
  end
end

大多数 Devise 控制器方法都接受块,因此您也可以为注册、忘记密码等执行此操作。

Devise 提供了after_database_authentication回调方法。你对那里的当前经过身份验证的用户对象具有完全访问权限。

如果您想在每次成功登录后更新当前用户名,您可以像下面这样操作。

class User < ActiveRecord::Base
  devise :database_authenticatable
  def after_database_authentication
    self.update_attributes(:name => "your name goes here")
  end 
end
    配置
  • 设备以使用控制器更改配置/路由.rb devise_for :users, controllers: { ... , sessions: "sessions", ... }
  • 创建应用程序/控制器/sessions_controller.rb 或使用 Rails 生成它 g 设计:控制器用户 -c=会话

prepend_before_action

class SessionsController < Devise::SessionsController
  prepend_before_action :your_task, only: [:create] # Change this to be any actions you want to protect.
  private
  def your_task
    return if your_task_is_OK # if your task is good, return to the super method otherwise render the new
    self.resource = resource_class.new sign_in_params
    respond_with_navigational(resource) do
      flash.now[:alert] = "your notice message"
      render :new
    end
  end 
end

最新更新