0
votes

I'm writing some script using mechanize(ruby) to test my site, when I make a get request to the login page, I get the html which includes CSRF token in the login form that is different from the CSRF stored in rails session, so when submitting a post request with login data, an error is generated Can't verify CSRF token authenticity and I can't login. This doesn't happen when logging from a browser normally, so any thought ?

Note: The CSRF returned when using mechanize to fetch the login page, always has the same value over all my tests today and yesterday! I don't know if this is helpful or not.

My code:

agent = Mechanize.new
page = agent.get('http://localhost:3000')
form = page.forms.last
form['user[email]'] = 'my email'
form['user[password]'] = 'password'
form.submit
2

2 Answers

0
votes

I faced this problem before, I asked on different Q and A sites but no useful answers I got it.

the only solution I found this :

skip_before_filter :verify_authenticity_token

it will skip the CSRF verification I think it will good for test environment for sure not for production. I wish to find other solution.

0
votes

okay, i know this topic is quite old, but I stumbled upon this and needed a working solution myself and here we go:

please set your credentials first and start your local server, then run the script.

require 'mechanize'
require 'nokogiri'
require 'open-uri'

# set global login credentials
$email = "[email protected]"
$password = "your-password"

# generate a mechanize agent object for persistent "browsing"
a = Mechanize.new { |agent| agent.user_agent_alias = 'Mac Safari' }

def form_login(a)
  # get the desired page with the login form
  a.get('http://localhost:3000/users/sign_in') do |page|

    # search the current csrf-token in the head of the document
    csrf_token = page.search('//meta[@name="csrf-token"]/@content')

    # now let's dive into the form, that asks for email, password
    # and for the authenticity_token in a hidden field
    login_result = page.form_with(:id => 'new_user') do |login|

      login.field_with(:name => 'user[email]').value = $email
      login.field_with(:name => 'user[password]').value = $password
      login.field_with(:name => 'authenticity_token').value = csrf_token

      # check output in console
      puts login.values

      # submit the form
      login.submit
    end # of login block
  end
end


form_login(a)