Not able to retrieve user_id from another controller. Kindly request for your help
mariosknl opened this issue · 5 comments
Please, for a bug report fill in the following template. Before that, make sure to read the whole README and check if your issue is not related with CORS.
Feature requests and questions about devise-jwt
are also accepted. It isn't the place for generic questions about using devise
with an API. For that, read our wiki page or ask somewhere else like stackoverflow
Expected behavior
I am using devise & devise-jwt for my User Authentication System. I'm building a full-stack project using Rails for the API and React & Redux for the front-end. Also, I have set up my Rails API so each time a user signs in, I'm setting a cookie in the browser. Everything works perfectly for me up to this point. So, I also have another controller that I'm using for the like functionality. While executing methods in that controller trying to retrieve the user data stored in the same cookie I'm getting NIL JSON Web Token. The cookie is unreachable for some reason. Can you please help me out with that?
Actual behavior
I was expecting to get the user_id.
Steps to Reproduce the Problem
Debugging information
Provide following information. Please, format pasted output as code. Feel free to remove the secret key value.
- Version of
devise-jwt
in use => devise-jwt (0.8.0) - Version of
rails
in use => rails (6.0.3.3) - Version of
warden-jwt_auth
in use - Output of
Devise::JWT.config
- Output of
Warden::JWTAuth.config
- Output of
Devise.mappings
- If your issue is related with not getting a JWT from the server:
-
Involved request path, method and request headers
`## Cors file
allow do
origins 'http://localhost:3001'resource '*',
headers: %w(Authorization),
credentials: true,
expose: ["Authorization"],
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end`
-
SessionsController
` class Users::SessionsController < Devise::SessionsController
respond_to :json
before_action :revoke_preexisting_token, only: %i[create destroy]
include ActionController::Cookies
def create
@user = User.find_by(username: params[:user][:username])
if @user&.valid_password?(params[:user][:password])
token = encode_token({ user_id: @user.id, refresh_token: 'token' })
cookies[:refresh_token] = { value: token, httponly: true, same_site: :none, secure: true }
render 'sessions/logged?.json.jbuilder'
else
render json: { message: 'Wrong username or password' }
end
end
def logged?
byebug
return unless cookies[:refresh_token]
token = JWT.decode(cookies[:refresh_token], ENV['devise_secret_key'])
@user = User.find(token[0]['user_id'])
render json: { message: 'no user is logged in' } unless @user
render 'sessions/logged?.json.jbuilder'
end
def delete
cookies.delete :refresh_token
render json: { message: 'log out success' }
end
private
def respond_with(resource, _opts = {})
render json: resource
end
def respond_to_on_destroy
head :ok
end
def refresh_token
cookies.encrypted[:refresh_token]
end
def revoke_preexisting_token
return unless refresh_token
RefreshToken.find_by(token: refresh_token)&.revoke
end
protected
If you have extra params to permit, append them to the sanitizer.
def configure_sign_in_params
devise_parameter_sanitizer.permit(:sign_in, keys: [:username])
end
end
`
Like Controllerr
`module Api
module V1
class LikesController < ApplicationController
respond_to :json
before_action :authenticate_user!
before_action :find_instrument
include ActionController::Cookies
def index
@likes = Like.all
render 'likes/index.json.jbuilder'
end
def create
byebug
token = JWT.decode(cookies.signed[:refresh_token], ENV['devise_secret_key'])
@user = User.find(token[0]['user_id'])
@instrument.likes.create(user_id: @user.id)
end
def destroy
@like.destroy
end
private
def find_instrument
@instrument = Instrument.find(params[:instrument_id])
end
def find_like
@like = @instrument.likes.find(params[:instrument_id])
end
def revoke_preexisting_token
byebug
RefreshToken.find_by(token: refresh_token)&.revoke
end
end
end
end
`
- Response headers for that request
- If your issue is related with not being able to revoke a JWT:
- Involved request path, method and request headers
Hi @mariosknl ! The first thing you should consider is if you need JWT authentication. You said you're using cookies, so in fact I see no need and you can stick with raw devise library.
Thanks for your message in the first place. Well, I am setting the cookies in the browser. This is done via the sessions controller. So, I want to grab the current user id stored in the cookies in another controller. Can this happen somehow?
What do you mean I dont need raw devise library?
You JUST need devise, you don't need devise-jwt. devise-jwt is useful when you don't have cookies, as it allows authentication through HTTP headers. But if you can use cookies, you don't need to add this extra layer of complexity.
Closing for now, feel free to add more comments if needed