Return JWT token when user signs in rails

Multi tool use
Multi tool use


Return JWT token when user signs in rails



Having an issue with getting JWT token using devise gem and devise-jwt gem. This is how my confirmation looks like.


devise gem


devise-jwt gem



devise.rb


Devise.setup do |config|

config.jwt do |jwt|
jwt.secret = SECRETS.devise_jwt_secret_key
jwt.dispatch_requests = [ ['POST', %r{^/authentication_tokens/create$}] ]
end
end



user.rb


class User < ApplicationRecord

devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:jwt_authenticatable, jwt_revocation_strategy: Devise::JWT::RevocationStrategies::Null

end



authentication_tokens_controller.rb


class Api::V1::AuthenticationTokensController < Devise::SessionsController
include Devise::Controllers::Helpers
skip_before_action :verify_authenticity_token

prepend_before_action :require_no_authentication, only: [:create]

before_action :rewrite_param_names, only: [:create]

def new
render json: { response: "Authentication required" }, status: 401
end

def create
self.resource = warden.authenticate!(auth_options)
sign_in(resource_name, resource)
yield resource if block_given?
render json: {success: true, jwt: current_token, response: "Authentication successful" }
end

private

def rewrite_param_names
request.params[:user] = {email: request.params[:email], password: request.params[:password]}
end

def current_token
request.env['warden-jwt_auth.token']
end

end



routes.rb


get 'home#secret'
devise_for :users
resources :tasks
#other routes for the website removed for brevity

namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :users
devise_scope :user do
post '/authentication_tokens/create', to: "authentication_tokens#create"
end
end
end



For some reason request.env['warden-jwt_auth.token'] returns null all the time, however, the user is authenticated.
Is there anything that I need to add to get the JWT token when a user signs in?


request.env['warden-jwt_auth.token']


null



Update - routes and namespacing



After days of debugging, I believe I have found the source of my problem. My app has a frontend which uses normal routes. The code above doesn't work however if I do something like the code below. All is good.


scope :api, defaults: {format: :json} do
devise_for :users, controllers: {sessions: 'v1/authentication_tokens'}
end



Is there a way of namespacing the devise_for for me API even though it has been used above for the website?


devise_for




2 Answers
2



I've briefly looked on your issue and, it's probably wrong, but something for you to give a try:



looking on the following lines


def create
self.resource = warden.authenticate!(auth_options)
end

def current_token
request.env['warden-jwt_auth.token']
end



If you say that user is being authenticated even with nil returned from current_token method, so that means that jwt is passing correctly, but your way of fetching it is wrong.


nil


current_token



Try to debug self.resource = warden.authenticate!(auth_options) line and see what contains inside auth_options, probably you can take JWT from there, or you just trying to get warden-jwt_auth.token in a wrong way. Try to debug this line as well and see if you should probably take "warden-jwt_auth.token" from request.headers["warden-jwt_auth.token"], or something like this. Just print out the whole response of your request and search by needed header.


self.resource = warden.authenticate!(auth_options)


auth_options


warden-jwt_auth.token


request.headers["warden-jwt_auth.token"]



I hope this helps!



You just need to make your route RESTful.



routes.rb


post '/authentication_tokens', to: "authentication_tokens#create"



devise.rb


config.jwt do |jwt|
jwt.secret = SECRETS.devise_jwt_secret_key
jwt.dispatch_requests = [ ['POST', %r{^/authentication_tokens$}] ]
end





Tried this but I'm afraid it doesn't work.
– Benjamin
Jul 3 at 22:05





@Benjamin is there anything that you didn’t mentioned in your example? I’ve reproduced issue with your example and fixed it by this way.
– Alex Tatarnikov
Jul 3 at 23:00





after debugging further I realise that the problem is actually with the routes. Please see my update.
– Benjamin
Jul 4 at 10:58






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Dy FWrhaM1ktmKjdl
5utDGEcv3EsQfIwV0PUhQVF0 PV76,nTxS9z rjUat5g0v3NkHEG61rwLVm7CiUM58OuptkDbg6rs 6LLFfXa RR12kntHcc38xbBx

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications