I think reading CSRF-value from DOM is not a good solution, it's just a workaround.
Here is a document form angularJS official website http://docs.angularjs.org/api/ng.$http :
Since only JavaScript that runs on your domain could read the cookie, your server can be assured that the XHR came from JavaScript running on your domain.
To take advantage of this (CSRF Protection), your server needs to set a token in a JavaScript readable session
cookie called XSRF-TOKEN on first HTTP GET request. On subsequent
non-GET requests the server can verify that the cookie matches
X-XSRF-TOKEN HTTP header
Here is my solution based on those instructions:
First, set the cookie:
# app/controllers/application_controller.rb
# Turn on request forgery protection
protect_from_forgery
after_action :set_csrf_cookie
def set_csrf_cookie
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
Then, we should verify the token on every non-GET request.
Since Rails has already built with the similar method, we can just simply override it to append our logic:
# app/controllers/application_controller.rb
protected
# In Rails 4.2 and above
def verified_request?
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end
# In Rails 4.1 and below
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…