测试用户是否刚刚使用Devise登录

时间:2013-03-19 04:01:40

标签: ruby-on-rails devise active-model-serializers

如果他们刚刚登录,我想在我的JSON响应中包含用户的authentication_token,以便我的API的使用者可以跟踪它并验证将来的请求。但我不想包含令牌。我正在使用Active Model Serializers来自定义我的JSON输出:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :authentication_token

  def include_authentication_token?
    # what to put here?
  end
end

Devise会话控制器使用respond_with resource,其中resource是登录用户,因此默认情况下它将使用UserSerializer。我可以自定义Devise控制器,但我宁愿使用include_authentication_token?。在Devise中是否有一些方法在用户刚刚登录时返回true(即响应来自Devise :: SessionsController)?

2 个答案:

答案 0 :(得分:0)

虽然当前请求不会在ActiveModel::Serializer的子类中自动提供,但您可以通过将其包含在options的调用中轻松将其传递到序列化程序的UserSerializer.new哈希。

如果明确创建序列化程序,请执行以下操作:

UserSerializer.new(@user, scope: current_user)

这意味着您只需传递一个名为request的第二个选项:

UserSerializer.new(@user, scope: current_user, request: request)

从那时起,您可以通过调用options[:request]来访问序列化程序中的当前请求。例如,要检查UserSerializer内的当前控制器,只需检查

的值
options[:request].params[:controller]

如果它出现为"devise/sessions",则可以包含令牌。否则,如果您使用标准的Devise控制器来处理登录,您可能必须将Devise::SessionsController子类化并重新路由到新控制器:

# app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    respond_with resource, location: after_sign_in_path_for(resource), request: request
  end
end

# config/routes.rb
devise_scope :user do
  post "sign_in" => "sessions#create", as: :user_session
end

请注意我还没有测试过。在阅读ActionController::MimeResponds#respond_with的{​​{3}}时,似乎任何给#respond_with的选项都会向下传递给响应者,响应者被ActionController::Serialization劫持,看起来像{{3}一直到resource的Serializer。

祝你好运!

答案 1 :(得分:-1)