Knock: Issue JWT token on user create

Created on 9 Nov 2017  路  7Comments  路  Source: nsarno/knock

I would like to send a JWT token when the user signs up so that they don't have to login again after signing up. Should this happen in two requests? One to users_controller#create then one to user_token_controller#create? Is there a security risk with not forcing the user to explicitly login after account creation? I notice some apps do this, some apps don't.

It would be awesome if Knock had a static site with examples or just a directory with code samples.

Most helpful comment

This is hacky but you try to reproduce the same steps that knock does to generate the token. I looked through the source code at auth_token_controller.rb#7.

    def create
      render json: auth_token, status: :created
    end

  private

    ...

    def auth_token
      if entity.respond_to? :to_token_payload
        AuthToken.new payload: entity.to_token_payload
      else
        AuthToken.new payload: { sub: entity.id }
      end
    end

Since it's a private method, you can just duplicate it, and new up an AuthToken after you create your user.

class Api::UserController < Api::BaseController

  def create
    user = User.new(params)
    if user.save
      # If your User model has a `to_token_payload` method, you should use that here
      auth_token = Knock::AuthToken.new payload: { sub: user.id }
      render json: auth_token, status: :created
    else
      render json: { error: user.errors.full_messages }, status: :unprocessable_entity
    end
  end
end

Some official support would be nice though. I wouldn't actually trust this not to break 馃槖

All 7 comments

Making two requests is the way I am doing it. It would be great to have a method to generate a token for a user (maybe there is one I don't know about?). That way, with user registration, you can create a user and return their details as json, plus return the jwt.

@mhluska There are a number of reasons not to log a user in upon creation - verifying they have access to the email they listed would be one. Still, I don't think it is necessarily an across the board bad practice, so it would be great to have the option to do so.

I am also interested in this. I would love a code sample to show some proper flows. I hear this gem mentioned a lot but I am curious as to why I can't find much in the way of documentation.

+1 on this

I'm struggling to find anything suggesting how this might done or what I should do instead. In terms of UX I'd prefer to not have the user have to enter the details again to sign in.

Anyone have any ideas?

This is hacky but you try to reproduce the same steps that knock does to generate the token. I looked through the source code at auth_token_controller.rb#7.

    def create
      render json: auth_token, status: :created
    end

  private

    ...

    def auth_token
      if entity.respond_to? :to_token_payload
        AuthToken.new payload: entity.to_token_payload
      else
        AuthToken.new payload: { sub: entity.id }
      end
    end

Since it's a private method, you can just duplicate it, and new up an AuthToken after you create your user.

class Api::UserController < Api::BaseController

  def create
    user = User.new(params)
    if user.save
      # If your User model has a `to_token_payload` method, you should use that here
      auth_token = Knock::AuthToken.new payload: { sub: user.id }
      render json: auth_token, status: :created
    else
      render json: { error: user.errors.full_messages }, status: :unprocessable_entity
    end
  end
end

Some official support would be nice though. I wouldn't actually trust this not to break 馃槖

+1

@hanchennz is there any method exists which will return JWT of currently logged in user without creating a new JWT again and again?
Actually I need this in my specs for testing every API call.

Thanks @hanchennz

Was this page helpful?
0 / 5 - 0 ratings