Rails Shows "Warning: Can't Verify Csrf Token Authenticity" from a Restkit Post

Rails shows WARNING: Can't verify CSRF token authenticity from a RestKit POST

You can safely remove the warnings with the following:

skip_before_filter  :verify_authenticity_token

This should go into every Rails API controller that you have, or if you have a base_controller for all API controllers then put it there.

If you can also access your app through a web browser then do not put this line in the application_controller as you will be creating a security vulnerability.

It is safe to remove csrf for API calls as the particular vulnerability can only be executed through a web browser.

Update 16th December 2013

I've seen some links to this answer and some other content which suggests a clarification. An API may be vulnerable to CSRF if you use web based authentication methods to authenticate the API - e.g. sessions or cookies.

There is some good detail in Is your Web API susceptible to a CSRF exploit?.

My advice still stands for users of RestKit as user credentials are unlikely to be based on sessions or cookies but rather usernames or api keys.

If your API can be authenticated with session or cookies then you should avoid skipping : verify_authenticity_token and you should think about moving to api key based authentication.

If your API can be authenticated with a username and password that is also used to authenticate on the web there is still a potential exploit, although it is less serious as it would require the user to type in their username and password to your site in the HTTP Auth challenge box while visiting the site with the exploit. Again, for the best security you should think about moving to api key based authentication.

It's worth noting that I don't agree that you need to add :only => [:your_method] for additional protection, provided that you have isolated api controllers, your api is not mixed with your web responses and you are not using session or cookies. If these are in place you can safely add the skip_before_filter into a base_controller for your api.

AngularJS - $http POST with Rails 3.2.3

This can be better implemented using a Contacts service. Please define a Contacts service in app/assets/javascripts/services.js.erb as shown below:

var servicesModule = angular.module('<your app name>',
[<list of modules needed by this app>]);

servicesModule.factory('Contacts', function($resource) {
var ContactsService = $resource('/contacts/:contact_id', {}, {
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
});
return ContactsService;
});

Change the addContact method in the controller as shown below:

  function ContactListCtrl($scope, $http, Contacts) {
...
...
...
$scope.addContact = function () {
var newContact = {
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
};

var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data.
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
});
};
...
...
...
}
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];

In addition to this, you can simplify the $http.get(...) part also. You can use Contacts.index();

Note:

  • If you gave ng-app="MyAppName" then please replace <your app name> with MyAppName.
  • <list of modules needed by this app> needs to the replaced by a comma-separated list of strings representing any modules needed by your application.

Ruby - RESTful API

The easiest way is to put this line into your controller.

class UserController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
puts params
end
end

As you are newbee so not for getting stuck into one thing use above method. And for details see this link

And also check your permitted params.

Another solution to CSRF token is to pass it in headers like:

headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}

How to POST an object to rails using RestKit?

I think the inverseMapping selector should be enough to make a serialization mapping

RKManagedObjectMapping *listMapping = [RKManagedObjectMapping mappingForClass:[List class]];
listMapping.primaryKeyAttribute = @"listID";

[listMapping mapAttributes:@"title", nil];
[listMapping mapKeyPath:@"id" toAttribute:@"listID"];
[manager.mappingProvider setMapping:listMapping forKeyPath:@"list"];
//this should be enough
[manager.mappingProvider setSerializationMapping:[listMapping inverseMapping] forClass:[List class]];

Edit:

according to our chat conversation, the warnings produced by RestKit were caused by the fact that the server response was lacking the root KeyPath (returned as naked array). To solve the problem we need to tell RestKit to use specific mapping to map the response:

mapping = [[[RKObjectManager sharedManager] mappingProvider] mappingForKeyPath:@"list"];
[[RKObjectManager sharedManager] postObject:newList mapResponseWith:mapping delegate:self];

Create User in Devise from JSON

Your rails app is expecting JSON in this form :

{"user":{"email":"test@example.com", "password":"Test123", "password_confirmation":"Test123"}}

But by default RestKit is sending this :

{"email":"test@example.com", "password":"Test123", "password_confirmation":"Test123"}

To add "user" you just need to set the rootKeyPath like this:

RKObjectMapping *userSerializationMapping = [userMapping inverseMapping];
userSerializationMapping.rootKeyPath = @"user";
[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:userSerializationMapping forClass:[User class]];


Related Topics



Leave a reply



Submit