I want to include a user's authentication_token
in my JSON response if they just logged in so that a consumer of my API can keep track of it and authenticate future requests. But I do not want to include the token otherwise. I am using Active Model Serializers to customize my JSON output:
class UserSerializer < ActiveModel::Serializer
attributes :id, :email, :authentication_token
def include_authentication_token?
# what to put here?
end
end
The Devise session controller uses respond_with resource
where resource is the logged-in user, so by default it will use the UserSerializer. I could customize the Devise controller, but I would rather use include_authentication_token?
. Is there some method in Devise that will return true when a User just logged in (ie, the response is coming from Devise::SessionsController)?
While the current Request is not automatically available within your subclass of ActiveModel::Serializer
, you can easily pass it into the serializer's options
hash by including it in your call to UserSerializer.new
.
If you explicitly create your serializer like:
UserSerializer.new(@user, scope: current_user)
That means you can simply pass a second option called request
:
UserSerializer.new(@user, scope: current_user, request: request)
From then on, you can access the current Request in your serializer by calling options[:request]
. For example, to inspect the current controller inside UserSerializer
, simply check the value of
options[:request].params[:controller]
If it comes up as "devise/sessions"
, you're OK to include the token. Otherwise, if you're using the standard Devise controllers to handle sign-ins, you'll probably have to subclass Devise::SessionsController
and reroute sign-ins to your new controller:
# 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
Please note I haven't tested this yet. In reading the source for ActionController::MimeResponds#respond_with
, it appears that any options given to #respond_with
will be passed downward to the responder, which is hijacked by ActionController::Serialization
and it looks like the options are passed all the way into the resource
's Serializer.
Good luck!
Maybe this will help you.
- (Boolean) signed_in?(scope = nil)
And on stackoverflow Devise how to add signed in check in custom session controller
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.