Multiple devise auth for WEB and API

Problem Statement

I’m Newbie in Rails and following this tutorial for setting up JWT based authentication in API, and working on an existing web application that uses Devise. My task at the moment is to add a JSON API to the application.

This rails project works fine for a web applications. However, Incase of API I’m getting empty resource while I still have value in params.


Environment

rails (6.1.4)

devise (4.8.0) devise-jwt (0.9.0)

warden (1.2.9) warden-jwt_auth (0.6.0)


Controller & Route

app/controllers/api/v1/users/registrations_controller.rb

class Api::V1::Users::RegistrationsController < Devise::RegistrationsController
    respond_to :json
    skip_before_action :verify_authenticity_token
  
    # POST /resource
    def create
      super
    end
  
    private
    def respond_with(resource, _opts = {})
    if resource.persisted?
        render json: {
        status: { code: 200, message: "Signed up sucessfully." },
        data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
        }
    else
        render json: {
        status: { message: "User couldn't be created successfully. #{resource.errors.full_messages.to_sentence}" }
        }, status: :unprocessable_entity
    end
    end
end

config/routes.rb

# For Web 
devise_for :users, controllers: { registrations: "registrations" }
# Authentication  
devise_scope :user do
    get "/login" => "devise/sessions#new", as: :login
    get "/logout" => "sessions#destroy", :as => :logout
    get "/signup" => "registrations#new", :as => :signup
    scope "my" do
      get "profile", to: "registrations#edit"
      put "profile/update", to: "registrations#update"
    end
end

authenticated :user do
    resources :dashboard, only: [:index] do
      collection do
        get :home
      end
    end
end

unauthenticated do
    as :user do
      root to: "devise/sessions#new", as: :unauthenticated_root
    end
end

# For API 
namespace :api do
    namespace :v1 do

      devise_for :users, path: '', path_names: {
        sign_in: 'login',
        sign_out: 'logout',
        registration: 'signup'
      },
      controllers: {
        sessions: 'api/v1/users/sessions',
        registrations: 'api/v1/users/registrations'
      }
    end
end

Debugging information

app/controllers/api/v1/users/registrations_controller.rb

|    66:   private
|    67:     def respond_with(resource, _opts = {})
|    68:       byebug
| => 69:       if resource.persisted?
|    70:         render json: {
|    71:           status: { code: 200, message: "Signed up sucessfully." },
|    72:           data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
|    73:         }
| (byebug) resource
| #<User 
    id: nil, 
    email: "", 
    first_name: "", 
    last_name: "", 
    role: "member", 
    created_at: nil, 
    updated_at: nil, 
    jti: nil
>

| (byebug) params
| #<ActionController::Parameters 
    {
        "email"=>"test@test.com", 
        "first_name"=>"John", 
        "last_name"=>"Wick", 
        "password"=>"password", 
        "controller"=>"api/v1/users/registrations", 
        "action"=>"create", 
        "registration"=>{
            "email"=>"test@test.com", 
            "first_name"=>"John", 
            "last_name"=>"Wick", 
            "password"=>"password"
        }
    } permitted: false>

  • Request
curl -X POST \
http://127.0.0.1:3000/api/v1/signup \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{
    "email": "test@test.com",
    "first_name": "John",
    "last_name": "Wick",
    "password": "password"
}'
  • Response
{
    "status": {
        "message": "User couldn't be created successfully. Email can't be blank and Password can't be blank"
    }
}