Search code examples
ruby-on-railsapiruby-on-rails-4titaniumstrong-parameters

Rails POST to API Not Working


Developing a Titanium Alloy JS android app and have a rails 4.1 app that is serving an API for authentication. Here is the code

  def valid_login?
    ApiAuthenticator.new(user,filtered_params[:password]).valid?
  end

  def user
    @user ||= User.find_by(email: filtered_params[:email])
  end

  def filtered_params
    params.permit(:email, :password)
  end

I have tried this multiple ways but still get this error.

Started POST "/api/login" for 192.168.1.64 at 2015-02-27 16:52:52 -0600
Processing by Api::V1::LoginController#create as JSON
  Parameters: {"password"=>"[FILTERED]", "email"=>"rt@c.com"}
Unpermitted parameter: format
  [1m[35mUser Load (0.1ms)[0m  SELECT  "users".* FROM "users" WHERE "users"."email" = $1 LIMIT 1  [["email", "rt@c.com"]]
Unpermitted parameter: format
Completed 400 Bad Request in 5ms (Views: 0.2ms | ActiveRecord: 0.8ms)

When i do a puts on the filtered_params i get this

{"email"=>"rt@c.com", "password"=>"password"}

I have tried this multiple ways including

  1. Using scaler everywhere (i.e. params.permit(:email))

  2. Accessing the has with symbols or string (this is hash with indifferent access that is returned by params.permit call

SOLUTION

I am using Titanium Studio (titanium alloy) to develop this and i was rendering the incorrect error code of 400. I should have rendered a 401. I was able to parse the message and display the proper error to the user on login. That code looks like this in titanium alloy controller

function login() {
    var xhr=Titanium.Network.createHTTPClient();    
    xhr.open('POST', url_login);

    xhr.onload = function(){
     if(this.status == '200'){
            tokenResponse = JSON.parse(this.responseText);
            setToken(tokenResponse.token);          
            Alloy.Globals.logged_in = true;
            redirectToIssues();
     }        
    };

    xhr.onerror = function(e){
        tokenResponse = JSON.parse(this.responseText);
        alert(tokenResponse.message);
        };

    var params = {
        'email' : $.email.value,
        'password' : $.password.value
    };
     xhr.send(params);
}

Solution

  • You don't actually need to use permit at all here

      def valid_login?
        ApiAuthenticator.new(user,params[:password]).valid?
      end
    
      def user
        @user ||= User.find_by(email: params[:email])
      end
    

    permit is only useful when you are doing mass assignment, ie things like User.create(params[:user])