Drupal Login: Persistent login prompt without an error message

Drupal users may sometimes fail to login while using a valid username and password withut even getting an error message. In such situations, the login screen/box is persistently presented on attempted logon. A quick and temporary fix to this problem is to delete cookies and then try to login again. The occurance of this varies from one browser to another and it has been observed Internet Explorer, konqueror, Safari and even firefox with the most common cases appearing in IE 6

The cause of this bug

This session ID/cookie based bug is linked to the persistence of the anonymous cookie even after logon - explanation:

  1. Anonymous user arrives at the forst page of a Drupal powered website [session cookie is created]
  2. User attempts to login adn is validated [the anonymous cookie is not deleted]

Analysis of technical background

Since the anonymous cookie is not deleted, the state that is maintained for this user is that of an anonymous user although in the drupal watchdog/log, the user appears to have been authenticated.

Based on this fact, deleting cookies after loading the first page or before any successful login attempt eliminates this problem and allows the user to login without any problems. The problem will however recur on subsequent login attempts and will require manual deletion of cookies.

Common descriptions and resolution attempts

The following bugs and forum discussions on the Drupal website are have valuable information that can aid in understanding the nature of the problem, as well as provide components for the following solution:

  • http://drupal.org/node/6696
  • http://drupal.org/node/53838
  • http://drupal.org/node/19113
  • http://drupal.org/node/23449

Some solutions involve modifying PHP settings to stop the use of cookies and use URL appended SESSION ID strings. This may solve the persistent cookie problem, but it creates and urgly URL not idealfor search engines optimization.

Solution

This bug has been reported on the Drupal support section and there have been a number fo solutions that do not seem to work in all cases. It is clear from the above as well as other perspectives that the problem lies with the continued existence of the cookies created with the anonymous session. A practical solution would create a new and distinguishable session for ever logged-in user to avoid carry-over of state information from the anonymous session or any other concurrent or unexpired PHP sessions.

user.module contains functions and operations for user login and status management and it is in this module that the bug can be rectified. As explained in one of the above URLs fromt he Drupal Support forum, replacing the user module from version 4.6 with that from version 4.5 has been known to eliminate the bug in some cases. but we should identify the problem, understand it and them create a solution.

Line 1900 - 1910 in the user.module of version 4.7 contains the function that authenticates users and creates a $user state variable.\

NB: This code has been updated. Please see a related discussion at: http://drupal.org/node/60584

<?php
user_module_invoke
('login', $form_values, $user);
//Silencing the next 3 lines and moving their actions lower after authentication
// $old_session_id = session_id();
// session_regenerate_id();
// db_query("UPDATE {sessions} SET sid = '%s' WHERE sid = '%s'", session_id(), $old_session_id);
}
}

function user_authenticate($name, $pass) {
global
$user;
// Try to log in the user locally. Don't set $user unless successful.
if ($account = user_load(array('name' => $name, 'pass' => $pass, 'status' => 1))) {
// next 3 lines: once authenticated, assign variable, regenerate the session ID, and update it in the DB
$old_session_id = session_id();
session_regenerate_id();
db_query("UPDATE {sessions} SET sid = '%s' WHERE sid = '%s'", session_id(), $old_session_id);
$user = $account;
};
?>


-----

It is at this point that the anonymous information in the session cookie should be dropped and replace with a new session for the logged-in user. by adding the line in bold we are regenerating the session ID att he moment of logon to break status with the anonymous user and start a new session for the new user.

This results in the creation of a new session ID every time the user logs on (on logoff, the same session ID persists to the anonymous sessiona dn this is not a problem). To expose the change of the session ID from log-on to log-off, you can place the following code in your page template to see how the change occurs (during development and testing only; please do not leave it on in the final website).

<?php
print ("<br />Session ID is ");
print ($_COOKIE["yourcookiename"]);
?>

If you find any problems implementing this solution of if the information provided is not clear and comprehensive, please comment on this post or give us feedback .

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thanks

This fix worked for me under Drupal 4.7.2. I also want to add that I redirected example.com to www.example.com in .htaccess and made sure $base_url in settings.php pointed to www.example.com as was also suggested to me. Thanks a lot for this!

Echoing thanks

Drupal 4.7.2, .htaccess redirect, up-to-spec $base_url. Thanks so much.

I take it back

It only worked the first time. Rats.

Thanks!

That worked!

Some solutions include only commenting the regenerate_sessionid() method. That too seems to work. How is this different from the method above? What are the pros and cons?

Thanks!

I did the above steps, it

I did the above steps, it still doesnt work for me. Can someone help here.

Login using .../user instead of the login block

Instead of logging in using the login box in the block column, can you try and access the login page at www.yourdomain.com/user and see if you will be able to login from there without the issue reappearing?

There have been reports that continuing to use the login block causes the problem.

Cookie Subdomain Causing Access Denied

I've found another bug that may be relevant here in Drupal 5.0, 2007-01-15

The following code in /sites/default/settings.php strips out www. and adds a dot to the front if it finds it:

if (isset($_SERVER['HTTP_HOST'])) {
$domain = '.'. preg_replace('`^www.`', '', $_SERVER['HTTP_HOST']);
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost', we don't set a cookie domain.
if (count(explode('.', $domain)) > 2) {
ini_set('session.cookie_domain', $domain);
}
}

I don't know why they would do this but on the site it means that the cookies will come out like this:

drupal URL -> cookie
www.mydomain.co.uk -> .mydomain.co.uk
subsite.mydomain.co.uk -> .subsite.mydomain.co.uk

When the drupal copy on subsite loads it gets the subsite cookie plus one for www as well. The newer of the two takes priority

If you have just logged in to subsite the session is correctly set up but a cookie for .mydomain.co.uk override it and this session id is not in the db so you get booted out.

Solution is to comment out ini_set('session.cookie_domain', $domain);

Hope that helps

Valid XHTML 1.0 Strict
This site is accepts Oped ID authentication for login
This Website is Built Using Semantic Markup and Cascading Style Sheets (CSS)
Some usage rights are reserved, please contact us for approval before using it