I'm currently using Devise with my Rails API app to authenticate users using devise-jwt.
This is what my User model looks like:
class User < ApplicationRecord
devise :database_authenticatable,
:registerable,
:jwt_authenticatable,
jwt_revocation_strategy: JWTBlackList
end
And config/routes.rb
is set up like this:
Rails.application.routes.draw do
devise_for :users,
path: '',
path_names: {
sign_in: 'login',
sign_out: 'logout',
registration: 'signup'
},
controllers: {
sessions: 'sessions',
registrations: 'registrations'
}
end
This is the sessions controller:
class SessionsController < Devise::SessionsController
private
def respond_with(resource, _opts = {})
render json: resource
end
def response_to_on_destroy
head :no_content
end
end
and the registrations controller:
class RegistrationsController < Devise::RegistrationsController
respond_to :json
def create
build_resource(sign_up_params)
resource.save
render_resource(resource)
end
end
I ran some Rspec tests shown below which were successful -
require 'rails_helper'
RSpec.describe SessionsController, type: :request do
let(:user) { create(:user) }
let(:url) { '/login' }
let(:params) do
{
user: {
email: user.email,
password: user.password
}
}
end
context 'when params are correct' do
before do
post url, params: params
end
it 'returns 200' do
expect(response).to have_http_status(200)
end
it 'returns JTW token in authorization header' do
expect(response.headers['Authorization']).to be_present
end
it 'returns valid JWT token' do
decoded_token = decoded_jwt_token_from_response(response)
expect(decoded_token.first['sub']).to be_present
end
end
end
But when I run the following POST request to /login
on Postman I get the following message:
On the right hand side you are able to see the rails console and server, showing the credentials are correct, but still we get 401
Any clues on what might be wrong? It's been difficult finding good resources on Devise using Rails API.
Thank you in advance
After digging through the SessionsController I found the reason it returned 401:
warden
was trying to authenticate an empty body. Fixed this by added Content-Type
to the request header