Knock: How to extend response?

Created on 30 Aug 2016  路  7Comments  路  Source: nsarno/knock

Sorry if this is a stupid question but i have read the docs and instructions at knock.rb 10 times but I can't figure out how to do that (ruby beginner).

So I want to extend the response from Authentication with the user data. I think I have to do sth like this:

app/controllers/user_token_controller.rb

class UserTokenController < Knock::AuthTokenController
  def create
    user = User.from_token_payload
    render json: {jwt: auth_token(user).token, user: user}, status: :created
  end
end

found that in another issue.. but It doesn't work:

NoMethodError (undefined method `from_token_payload' for #<Class:0x007fcf39f58498>):

this is how my user controller looks like (if interested):

app/controllers/api/v1/users_controller.rb

class Api::V1::UsersController < ApplicationController
  before_action :authenticate_user

  def index
    render json: User.all
  end

  def show
    @user = User.find(params[:id])
    render json: @user
  end

  def create
    @user = User.new(user_params)
    if @user.save
      render json: { status: 201, message: "User successfully saved", user: @user }
    else
      render json: { status: 422, error: @user.errors }
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end

end

thanks for any any help!

question

Most helpful comment

aaah okay thanks for clarification. I misunderstood the concept of to_token_payload!
I already thought about a second request but i thought it might me easier to extend the token response.
but thanks for your time and help @nsarno!

All 7 comments

Happy to help, although this issue does not seem directly related to Knock so I'll close it.

So I want to extend the response from Authentication with the user data.

Do you mean you want to add more data inside the token payload?

Then you want to implement User#to_token_payload.

Please refer to the customization section of the README / "Modify the token payload".

NoMethodError (undefined method `from_token_payload')

The error message is pretty explicit. You didn't implement User.from_token_payload.

Please refer to the customization section of the README / "Find the authenticated entity from the token payload".

Let me know if it helped!

Hi @nsarno! thank you for every help! You're right, I want to add more data to the response so that it looks like this:

{ "jwt": "weiqueiqweuqiweuqoweuqeoiuqweou", "user": { "name": "John", "email": "john@example" }}

like I understand the README i need to put the to_token_payload to my user model:
app/models/user.rb

class User < ApplicationRecord
  # some user stuff like validation here

  def to_token_payload
    # what to do now? :(
  end
end

Sorry, I'm a real newbie to ruby coming from frontend stuff.

The #to_token_payload only allows you to add more data inside the token. Which is only to be used by the API, not the client.

I don't believe sending user data belongs here. It would be more appropriate to make 2 separate requests. One to create the token and a second one to get user data.

You already have a users controller with a #show action that would allow you to do this.

e.g.

GET /api/v1/users/1

Make sure you pass the token in the authorization header.

Good luck!

aaah okay thanks for clarification. I misunderstood the concept of to_token_payload!
I already thought about a second request but i thought it might me easier to extend the token response.
but thanks for your time and help @nsarno!

I am unable to get to_token_payload to work. I've got this working so I am seeing jwt in response, but can't get id to show up to make the second request as you state above

GET /api/v1/users/1

Here is my user model

class User < ApplicationRecord
  has_secure_password

  def self.from_token_request request
    email = request.params["auth"] && request.params["auth"]["email"]
    self.find_by email: email
  end

  def self.from_token_payload payload
    self.find payload["sub"]
  end

  def to_token_payload
    {sub: id}
  end
end

I have tried this without from_token_request and from_token_payload as well and same result. I'm new to rails so i may be missing something. I'm using active_model_serializers, would this cause any problems?

Here is my user_token_controller.rb

class UserTokenController < Knock::AuthTokenController
end

This issue https://github.com/nsarno/knock/issues/158 helped me figure a solution out.

My articles might be useful:
https://medium.com/@sujal.kokh/extend-the-response-of-knock-in-rails-9cfdabe11dee

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maluramichael picture maluramichael  路  7Comments

rayway30419 picture rayway30419  路  5Comments

nowakov picture nowakov  路  4Comments

GregTheGreek picture GregTheGreek  路  3Comments

ernandejr picture ernandejr  路  3Comments