Proper way to submit a form via https?

Hi, I am trying to find the ‘recommended’ way of doing this and have
had little success so far.
I have a login form. I want this to submit via https. What I have
found I had to do was this:

<% form_for :user, :url =>{ :controller => :account, :action
=> :login, :only_path => false, :protocol => “https://” } do |form| %>
(get login and password)
<%end%>

This looks kind of crap and I am thinking there must be a nicer way! I
am using the SSLRequirement plugin but that really doesn’t work for
forms as all you can do is a redirect, by which time it is too late.

Also, it would be nice if there was a way to only include the protocol
attribute when I was in production mode as it is a hassle under dev!

Help!

Thanks.

How about setting :only_path => true ?
That way, the forms action attribute will contain only the relative
url to the target controller which implies https given that the
display of the form happened through https.

On Dec 28, 2007, at 7:22 AM, phil wrote:

This looks kind of crap and I am thinking there must be a nicer way! I
am using the SSLRequirement plugin but that really doesn’t work for
forms as all you can do is a redirect, by which time it is too late.

I’m not terribly experienced in this matter, but I believe that is
the correct way.

Also, it would be nice if there was a way to only include the protocol
attribute when I was in production mode as it is a hassle under dev!

You can try something like this in application.rb

def require_ssl
if request.ssl? || local_request?
return true
else
redirect_to :protocol => “https://” and return false
end
end

which says if the request is already ssl, or it’s local, return
true. Then in your controllers,

before_filter :require_ssl

it works for me.

Peace,
Phillip

which says if the request is already ssl, or it’s local, return
true. Then in your controllers,

before_filter :require_ssl

it works for me.

Peace,
Phillip

But won’t the end result of this be that the form will be submitted
via http (ergo having everything transmitted in clear text) and then
have it go ‘whoops, this should be https’ and redirect to https? This
method is what ssl_requirement does, which is good for secure pages,
just not secure form submissions.

Maybe I am doing something wrong, but, with :only_path => false I get:

but with it true I get:

Which looks like it is ignoring the protocol completely!
(I am running under rails 1.2.5 btw)

I am not displaying the form via https, as really there is no need.
The information on login (and registration) is not sensitive - just
the stuff the user fills in and submits.

On Dec 28, 2007, at 9:05 AM, phil wrote:

            end

Phillip

But won’t the end result of this be that the form will be submitted
via http (ergo having everything transmitted in clear text) and then
have it go ‘whoops, this should be https’ and redirect to https? This
method is what ssl_requirement does, which is good for secure pages,
just not secure form submissions.

If your initial submission is to https, then you shouldn’t have a
problem. So in your view, if you have as the action of the form

action=“https://some_url”

then it should be encrypted on the way. I actually wrestled with
this some and decided to go the way of PayPal. If you go to http://
www.paypal.com, you are immediately redirected to https://
www.paypal.com. I found that it’s easier to just run the whole site
in https than switch back and forth. And with my site being more an
online application than a “web site”, it makes more sense.

Peace,
Phillip

On Dec 28, 2007, at 2:22 PM, phil wrote:

This looks kind of crap and I am thinking there must be a nicer way! I
am using the SSLRequirement plugin but that really doesn’t work for
forms as all you can do is a redirect, by which time it is too late.

SSL Requirement if fine when the container page is already secure.

I normally use Secure Actions:

http://agilewebdevelopment.com/plugins/secure_actions

which allows declaration of secure actions as well and hooks into URL
generation to get the right protocol. I blogged some details about the
plugin here:

 http://www.advogato.org/person/fxn/diary/470.html

– fxn

Maybe I am doing something wrong, but, with :only_path => false I get:

but with it true I get:

This is correct. A relative path infers the missing pieces from the
current documents url.
Thus it’s not “ignoring” the protocol, but using the very same which
you used to display your form.

I am not displaying the form via https, as really there is no need.
The information on login (and registration) is not sensitive - just
the stuff the user fills in and submits.

Yes but if you display the form via https (maybe even enforcing that
with ssl_requirement), the form can infer the protocol. Try installing
the Firebug and TamperData extensions for Firefox to play around with
this stuff and see how the forms action is derived from the action
attribute and the documents url.

Along the same lines of this thread, I have a secure online form that
I am using to create and save accounts. I’m using SSL to process the
new accounts (ultimately we’ll be accepting credit cards). My
experience with using SSL is practically nil (at least in Rails). So
the account creation works locally AND in production when I refrain
from using SSL. However when I go through the https:// URL, the form
does not process, doesn’t provide any error messages, and simply
displays the “new” action again as if the data errorred out. I am
using the ssl_required plugin, too. All to no avail.

I have a temporary Comodo certified certificate and I do not get the
invalid certificate prompt at our production URL. It feels like I
might just be missing a detail pertaining to the SSL certificate or
whatnot that is a quick fix. At least I hope that’s the problem. If
you have any thoughts, feel free to share!

Thanks,

-e

But if I have/want a login widget at the top of every page the only
nice way to get that working with this method is to have every page
ssl’d. Which is ridiculous.

What I am doing now is this:
<% unless RAILS_ENV == ‘production’
url_options = { :controller => :account, :action => :do_login }
else
url_options = { :controller => :account, :action
=> :do_login, :protocol => ‘https://’, :only_path => false }
end %>

It’s a hack, but it works.

I decided to write this:
def secure_form_for(record_or_name_or_array, *args, &proc)
unless RAILS_ENV == ‘production’
url_options = {}
else
url_options = {:protocol => ‘https://’, :only_path => false }
end

options = args.last.is_a?(Hash) ? args.pop : {}
options = url_options.merge options

return form_for(record_or_name_or_array, options, &proc)

end

Anyone think this is crazy? Seems to work so far.

Actually, that didn’t quite work. This does:
def secure_form_for(record_or_name_or_array, *args, &proc)
unless RAILS_ENV == ‘production’
url_options = {}
else
url_options = {:protocol => ‘https://’, :only_path => false }
end

options = args.last.is_a?(Hash) ? args.pop : {}
if !options[:url].nil?
  options[:url] = url_options.merge options[:url]
else
  options[:url] = url_options
end

return form_for(record_or_name_or_array, options, &proc)

end