I have React app that is sending a Login request to Devise via my Rails backend. When I try to hit the Login endpoint it looks like my response contains HTML, the console error is:
Unexpected token < in JSON at position 0
However I don't see anything in the network tab. It simply says, "Failed to load response data."
I am suspicious that this is being caused because the method is somehow causing a redirect, as indicated by the Rails Console:
Started POST "/users/sign_in" for ::1 at 2020-04-06 11:10:51 -0700
Processing by SessionsController#create as */*
Parameters: {"user"=>{"email"=>"REDACTED", "password"=>"[FILTERED]"}, "session"=>{"user"=>{"email"=>"REDACTED", "password"=>"[FILTERED]"}}}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 12ms (ActiveRecord: 3.5ms | Allocations: 9110)
Here is my JS method that calls the Devise API:
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch(url, {
method: "POST",
headers: {
"X-CSRF-Token": token,
"Content-Type": "application/json"
},
body: JSON.stringify(userInfo)
})
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.catch(error => console.log(error.message));
}
And here is my sessions_controller.rb:
class SessionsController < Devise::SessionsController
protect_from_forgery with: :null_session
skip_before_filter :verify_authenticity_token, :only => :create
# POST /v1/login
def create
@user = User.find_by_email(user_params[:email])
return invalid_login_attempt unless @user
if @user.valid_password?(user_params[:password])
sign_in :user, @user
render json: @user
else
invalid_login_attempt
end
end
def is_admin
if current_user.admin?
render json: { response: "true" }
else
render json: { response: "false" }
end
end
def destroy
sign_out(@user)
render :json=> {:success=>true}
end
private
def invalid_login_attempt
warden.custom_failure!
render json: {error: 'invalid login attempt'}, status: :unprocessable_entity
en
def user_params
params.require(:user).permit(:email, :password)
end
end
end
And here is my routes.rb:
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'registrations', sessions: 'sessions' }
devise_scope :user do
get '/users/is_admin', to: 'sessions#is_admin'
end
root 'homepage#index'
get '*path', to: 'homepage#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end