We have a new web app constructed by another developer. My job was to implement a backend API for other programs to use to exchange XML data with the database. It was going pretty well, until the main app implemented devise to authenticate users. I figured I'd be able to tweak the curl command to log in then submit/request data, but it isn't going very well. I'm trying things like
curl --cookie-jar ~/Desktop/cjar --data "user[login]=<username>" --data "user[password]=<pwd>" --data "commit=Sign in" localhost:3000/users/sign_in
followed by
curl --cookie ~/Desktop/cjar --data "<root_node></root_node>" localhost:3000/my_update_method
my latest error message is
WARNING: Can't verify CSRF token authenticity
Completed 401 Unauthorized in 1ms
I guess that's better than the redirection messages I was getting, but I'm still not close to knowing what's going on.
I've found a few related posts that make me think this is partly related to devise, and partly related to automatic authentication done by Rails. When I look at the info being passed by the web page, I see authenticity_token and utf8 params that I don't know how to construct for my curl command.
I can keep trying stuff, but I'm new to both curl and authentication, so I'm sort of shooting in the dark, and hoping that someone can save me some time. I guess my questions are:
- Can this be done?
- Should this be done? If not, what other options do I have?
- One post suggested a way around the authentication, but is is possible for only the curl commands to require a login/pwd, but bypass any other validation, without affecting the main web app?
UPDATE 1:
Thanks for all the help, I appreciate it. The response to the first curl command (listed above) is now just a redirection to the login page, so logging in doesn't seem to take. Does anyone have any suggestions about where to start debugging that? Nothing is ever getting into the application, so there's no logging there to look at. Here's the content of the cookie, if it means anything to anyone:
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_localhost FALSE / FALSE 0 _glow_session BAh7B0kiCmZsYXNoBjoGRUZvOiVBY3Rpb25EaXNwxhc2g6OkZsYXNoSGFzaAk6CkB1c2VkbzoIU2V0BjoKQGhhc2h7ADoMQGNsb3NlZEY6DUBmbGFzaGVzewY6C25vdGljZUkiHFNpZ25lZCBpbiBzdWNjZXNzZnVsbHkuBjsAVDoJQG5vdzBJIg9zZXNzaW9uX2lkBjsARkkiJTIwODc1Y2VjM2ViNzlmZDE3ZjA4ZjVmMDAxNWMxMDU4BjsAVA%3D%3D--d90722b6da386630b33f57902447b440f30d0b2a
I've added skip_before_filter :verify_authenticity_token
to the controller that handles the api requests, and that eliminated the error I was seeing before.
UPDATE 2:
After some troubleshooting and debugging, I think I may actually be getting logged in okay, but when I execute the second curl, the development.log file shows
Started POST "/upsert_experiment" for 127.0.0.1 at 2013-10-16 12:14:12 -0500
Processing by WebServiceController#upsert_experiment as */*
Parameters: {"experiment_xml"=>"<experiment></experiment>"}
Completed 401 Unauthorized in 1ms
which leads me to think that the authorization is still the problem.
UPDATE 3:
I think the problem is just that skip_before_filter :verify_authenticity_token
isn't working.
I have
class ApplicationController < ActionController::Base
rescue_from DeviseLdapAuthenticatable::LdapException do |exception|
render :text => exception, :status => 500
end
protect_from_forgery
before_filter :authenticate_user!
end
and
class WebServiceController < ApplicationController
skip_before_filter :verify_authenticity_token
...
end
With this setup, I get "Completed 401 Unauthorized in 1ms". If I comment out the protect_from_forgery line in the superclass, it just works, so the forgery protection is definitely the problem. I just don't know how to solve it.