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!
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
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!