0

I'm new to angularJS and Rails,and I tried to building a Rails application with AngularJS

and now, I want to do a POST request to sent data insert database

Activity Controller

def create
        @activity = Activity.new(params[:activity])

        respond_to do |format|
            if @activity.save
                format.html {redirect_to activities_url}
                format.json { render activities_url, status: :created, location: @activity}
            end
        end

end

Activity Coffee JS

app = module('activity', ['ngAnimate'])
app.controller 'FormCtrl', ($scope, $http) ->
    config = {
        header: {
            'Content-Type': 'application/json'
        }
    }
    @test = ->
        $http.post('/activities.json', {title: 'test1'}, config).success (data, status) ->
            console.log(data)
            console.log(status)
return

Console log

Started POST "/activities.json" for ::1 at 2016-05-04 21:06:10 +0800
Processing by ActivitiesController#create as JSON
  Parameters: {"title"=>"test1", "activity"=>{"title"=>"test1"}}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms)

I created a button of ng-click to trigger test function but I got information like console log, How can I do to fix it?

1

3 Answers 3

2

There is a great answer here: Rails API design without disabling CSRF protection

The gist of it is that you can put the CSRF token in a cookie called XSRF-TOKEN like so:

# In my ApplicationController
after_filter :set_csrf_cookie

def set_csrf_cookie
  if protect_against_forgery?
    cookies['XSRF-TOKEN'] = form_authenticity_token
  end
end

You'll then have to overload the verified_request? method in your ApplicationController to load the token from where Angular will return it:

protected

def verified_request?
  super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end

(read the link I included though.. there are caveats, but I think you want something like this anyway... basically your login actions shouldn't be protected against csrf, but other potentially destructive actions should. You could achieve this with skip_before_filter.)

I hope that helps!

Sign up to request clarification or add additional context in comments.

7 Comments

Great answer, much better than mine.
Thanks! No offense intended by my comment on your answer, I just cringe when I think of the potential issues w/ going without it.
Thanks for answer. And now, I have new question, I success to sent data into database, but why I can't see the data update unless I refresh browser by myself ?
That's a whole other thing. Basically you'd ideally build an AngularJS service (docs.angularjs.org/api/ng/service) to wrap your interactions with the Rails api you're building. Then the service will take responses from Rails and update your Angular scope.
Are you seeing the data in your console? Your page would have to have some variable bound that you put data into.
|
1

I believe the quickest way of achieving this is with the helper method form_authenticity_token.

$http({
  method: 'POST',
  url: '<%= some_path %>',
  params: { 
    authenticity_token: '<%= form_authenticity_token %>',
    ... // Other params
  }
})

There is no need to disble CSRF which I don't recommend at all.

Comments

0

Your issue is a feature of rails designed to defeat so-called "Cross Site Request Forgery". The Rails team has described this in some detail on their website, but basically it's a generated token that seeks to ensure that the form that generates a request to the web api is the form you provide. This often causes hassles with single page AJAX apps.

The 'quick fix' would be to disable CSRF by adding something like this to your Controller.

protect_from_forgery :except => :create

Hope this helps!

2 Comments

While it is a 'quick fix' in that it makes things happen and removes the current road block, I think csrf is worth a few minutes of up front work to avoid any trouble in the chance your site/app becomes popular enough to become a target.
Don't disagree. CSRF is worth keeping around for production code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.