7

I'm using Drupal 7. The login page for my users is located at /user/login, so the default login path. I need that page to be encrypted using SSL so people aren't transmitting their passwords in the clear.

I have Apache configured so that the site can be navigated either over HTTP or HTTPS. However, I want to implement some rewrite rules so that all requests other than /user/login are made over HTTP because it is INFINITELY faster and will result in better user experience. I refuse to use Secure Pages at this point in time because of the bugged support in Drupal Core and I'm not going to patch Core manually. That means I'm left with using Apache rewrite rules.

I have the following rules:

<VirtualHost *:80>
  ...
  RewriteCond %{HTTPS} off
  RewriteCond %{REQUEST_URI} ^/user/login$
  RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [L,R]
  ...
</VirtualHost>

<VirtualHost *:443>
  ...
  RewriteCond %{HTTPS} on
  RewriteCond %{REQUEST_URI} !^/user/login$
  RewriteRule ^/(.*) http://%{HTTP_HOST}/$1 [L,R]
  ...
</VirtualHost>

Now to me, that makes sense, but Drupal doesn't seem to like it.

What's happening is as follows:

  1. If I navigate around the site using HTTP to any page other than /user/login, it works fine.
  2. If I navigate to /user/login over HTTP, I get redirected to the front page.
  3. If I navigate to any page over HTTPS, I get redirected to the front page over HTTP.
1
  • Very slow HTTPS pages may not be normal but indicate that your system is running low on entropy. Explanation and a way to fix it here.
    – tanius
    Commented Feb 19, 2017 at 12:45

3 Answers 3

8

You don't really need /user/login to be served via https; you need the user login form to be submitted via https.

You should take a look at the module securepages_prevent_hijack -- not to use it directly, since it depends on securepages, but to see how the login form is altered. Like so:

function securepages_prevent_hijack_form_alter(&$form, &$form_state, $form_id) {
  // Secure the login form, so that we always have a secure connection to transmit the
  // initial cookie.  Also, protect the password in transit.
  if ($form['#id'] == 'user-login-form' || $form['#id'] == 'user-login') {
    $url = parse_url($form['#action']);

    $base_path = base_path();
    $path = (!strncmp($url['path'], $base_path, drupal_strlen($base_path)) ? drupal_substr($url['path'], drupal_strlen($base_path)) : $url['path']);
    $options = array('secure' => TRUE);
    if (isset($url['query'])) {
      $options['query'] = $url['query'];
    }
    $form['#action'] = securepages_url($path, $options);
  }
}

You should also figure out whether the cookie that Drupal is setting for you is secure or not. This will depend on your settings in php.ini. Check to see if you have set session.cookie_secure to 1. If you have, then the cookie will not be sent to your http sessions, which could be why you are ending back at the home page (no session cookie == no session == no login info == log out). Of course, if the session.cookie_secure is 0, then it might be possible for other parties to observe your session cookies in transit, and masquerade as your users. Perhaps you have already considered this risk, but it does bear some consideration.

7
  • Interesting. Well, I looked through settings.php and php.ini and session.cookie_secure is not set anywhere. So you think I could just create a custom module that implements hook_form_alter and target the login form? I'm not really sure what securepages_url(...) does... Commented Feb 21, 2012 at 6:11
  • securepages_url is similar to the converse of parse_url; it's in the securepages module (of course), so you could look it up. It's more complicated than you need; you could just preg_replace the http to https in the $form['#action']. The reason form alter is better than your http-to-https redirect is that it will also work on login forms that are in a block on some page other than user/login. You can stick with your current technique if you don't need those. Of course, your real problem is going from https to http. You're going to have to track down why the session cookie is not persisting. Commented Feb 21, 2012 at 6:29
  • Make sure that RewriteCond %{REQUEST_URI} !^/user/login$ is working right; if this rule caught part of the login redirect process, then your password would be sent in the clear. Capture some packets with wireshark to make sure this is not happening. This might also help you figure out what's happening with your session cookie. I know I haven't answered your question, but hopefully this will get you started down the right track. Commented Feb 21, 2012 at 6:34
  • You've done a pretty good job at pointing me in the right direction. For example, I had no idea that different sessions persisted between HTTP and HTTPS, which obviously goes a long way in helping my understanding of the problem. I come from the Rails world, so, this is new to me :) Commented Feb 21, 2012 at 6:46
  • 1
    You might also find this recent DrupalPlanet article interesting: solotandem.com/… Commented Feb 21, 2012 at 18:26
4

I think the Secure Login module will also do what you want without requiring you to hack the core.

Secure Login module enables the user login and other forms to be submitted securely via HTTPS, thus preventing passwords and other private user data from being transmitted in clear text.

2

I think you can try Secure Pages again, as since then they've release the new stable version.

For Drupal 8, check: Secure Login module.

See also: Enabling HTTP Secure (HTTPS).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.