Handling 403 Forbidden Login Pages with (Ruby) Mechanize
Instead of having a dedicated login page, some sites return a 403 Forbidden HTTP status code and include the login form in an HTML body of a custom 403 page. For example, Drupal admin pages work this way. While this may seem a little odd, it works; all modern browser will display the HTML and few, if any, will note the Forbidden status.
Mechanize on the other hand raise an exception when it receives a 403 status. Fortunately, it returns the page it received as part of that exception. Here’s how to handle it:
mechanize = Mechanize.new
begin
login_page = mechanize.get("http://localhost/admin")
rescue Mechanize::ResponseCodeError => exception
if exception.response_code == '403'
login_page = exception.page
else
raise # Some other error, re-raise
end
end
login = login_page.form_with(:action => '/login') do |f|
f.field_with(:name => 'user').value = user
f.field_with(:name => 'password').value = password
end.submit
raise 'Login Failed' if login.body !~ /Logged in!/
This code also works in the case where you don’t get a forbidden status, so it can be used generically.
For bonus points you can use the same code in a Cucumber step by changing:
login_page = mechanize.get("http://localhost/admin")
to:
login_page = webrat.adapter.mechanize.get(path_to('the admin page'))
(assuming you’ve set up “the admin page” in paths.rb).
Comments