简体   繁体   中英

Customize Devise user JSON response on creation of a user account

How do I customize the JSON output on creation of a devise User?

### User.rb ###
class User < ActiveRecord::Base
  devise :database_authenticatable,
         :registerable, ...
  ...
end

### Routes.rb ###
...
devise_for :users, :controllers => {:registrations => "registrations"}
...

I've got some extra fields in my User table that are secret, but they get returned in the JSON response when I do a User creation via JSON like this:

$ curl -H "Content-Type: application/json" -d '{"user" : {"username":"someone","email":"someone@somewhere.com","password":"awesomepass"}}' -X POST http://localhost:3000/users.json

which returns:

{"user":{"secret_field_1":"some value","secret_field_2":"some value","created_at":"2013-07-25T21:24:50-05:00","email":"someone@somewhere.com","first_name":null,"id":3226,"last_name":null,"updated_at":"2013-07-25T21:24:50-05:00","username":"someone"}}

I'd like to hide those secret fields, but don't know how to customize the JSON response.

I've tried a standard ActiveRecord serializer:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :created_at, :updated_at, :email, :first_name, :last_name, :username
end

to no avail, I'm guessing because of Devise.

I just ran into the same issue. I haven't pinpointed exactly why but it looks like respond_with in Devise's SessionsController (tested on Devise 3.0 and active_model_serializers 0.8.1) doesn't trigger the ActiveModel::Serializer .

So I overrode respond_with in my controller:

class SessionsController < Devise::SessionsController

  def respond_with(resource, opts = {})
    render json: resource # Triggers the appropriate serializer
  end

end

It is, however, working in my RegistrationsController with respond_with . There I needed to do the following:

class RegistrationsController < Devise::RegistrationsController

  respond_to :json
end

I recently ran into this and overriding respond_with didn't fix the issue. I ended up overriding to_json in user.rb like so:

def to_json(arg)
  UserSerializer.new(self).to_json
end

Not sure what the extra arg is, but that seems to be required by one of the devise mixins.

I'm using the following:

  • Rails 4.2.0
  • Devise 3.4.1

Just a guess, but it sounds like rails is not finding your serializer and is using to_json() . Did you define active_model_serializer() in your model?

I just had the same problem, below is how I resolved it, very simple.

All these passed in active_model_serializers (0.9.5)

Override Devise registration method, and in your customize action:

def registration
  //Some process, and you get a @user when registration is successful.

  render :json => UserSerializer.new(@user)
end

If you want to pass some parameters to your customized Serializer(token for example), you can pass it in your action:

render :json => UserSerializer.new(@user).as_json({auth_token: your_token})

And in your serializer, just use:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :avatar_url, :auth_token

  def auth_token
    serialization_options[:auth_token]
  end
end

Depending on what you are doing with that JSON, you simply have to remove attributes you don't want from your serializer.

For example :

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :username
end

I presume that, in your case, you just want to do that.

But you also have the possibility to include an attribute on a specific condition :

class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :body, :author

  def include_author?
    current_user.admin?
  end
end

And finally you can override the attributes method to return the hash you need :

class PersonSerializer < ActiveModel::Serializer
  attributes :first_name, :last_name

  def attributes
    hash = super
    if current_user.admin?
      hash["ssn"] = object.ssn
      hash["secret"] = object.mothers_maiden_name
    end
    hash
  end
end

See README of ActiveModel::Serializers for more informations.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM