Home > Enterprise >  Filter chain halted as :authorize rendered or redirected
Filter chain halted as :authorize rendered or redirected

Time:07-16

I am hosting the backend of my application on Heroku and my frontend on Firebase (subdomain hosted by Firebase).

When I try to log in to my application, I get: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 In my Heroku logs I am noticing that I also get this error: Filter chain halted as :authorize rendered or redirected

Here is my ApplicationController:

class ApplicationController < ActionController::API
    include ActionController::Cookies
    rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity_response
    before_action :authorize

    private

     def authorize
        @current_user = User.find_by(id: session[:user_id])

        render json: { errors: ['Not authorized'] }, status: :unauthorized unless @current_user
    end

    def render_unprocessable_entity_response(exception)
        render json: { errors: exception.record.errors.full_messages }, status: :unprocessable_entity
    end

end

I also have rack CORS installed and configured as such:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins "*"

    resource "*",
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

Function to log in:

function handleSubmit(e) {
    e.preventDefault();
    setIsLoading(true);
    fetch("https://safe-depths-80660.herokuapp.com/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
      },
      body: JSON.stringify({ username, password }),
    }).then((r) => {
      setIsLoading(false);
      if (r.ok) {
        r.json().then((user) => onLogin(user));
      } else {
        r.json().then((err) => setErrors(err.errors));
      }
    });
  }

Login action:

def create
        user = User.find_by(username: params[:username])
        if user&.authenticate(params[:password])
            session[:user_id] = user.id
            render json: user
        else
        render json: { errors: ['Invalid username or password'] }, status: :unauthorized
        end
    end

I know origins * is bad, but am trying it for testing purposes. Please let me know if you have any ideas!

CodePudding user response:

The second log entry is normal as before filter halts execution in case @current_user is empty which seems to be part of authentication logic.

Double check in which line the JSON parsing is occurring and in which action. That should lead you to the root cause.

CodePudding user response:

It would be helpful to see the full server side error log and the form view. However, my hunch here is actually the error is happening before the login controller is hit. Rather, I think your request may be missing the authenticity token. Because you're posting the form via AJAX instead of the form handler, you'll need to manually add it to the headers of your request. Something like this may work

function handleSubmit(e) {
    e.preventDefault();
    setIsLoading(true);
    fetch("https://safe-depths-80660.herokuapp.com/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content // This is the authenticity token
      },
      body: JSON.stringify({ username, password }),
    }).then((r) => {
      setIsLoading(false);
      if (r.ok) {
        r.json().then((user) => onLogin(user));
      } else {
        r.json().then((err) => setErrors(err.errors));
      }
    });
  }
  • Related