Wordpress Login Redirect Problems

Jul 30, 2014

I inherited maintaining a group of wordpress sites that shared the same installation. Each site's database tables are setup using the domain name, minus the www, prepended to the wordpress tables.

For example, the site www.abcd.com has the tables:

abcd_com_commentmeta
abcd_com_comments
abcd_com_links
abcd_com_options
abcd_com_postmeta
abcd_com_posts
abcd_com_sk2_logs
abcd_com_sk2_spams
abcd_com_term_relationships
abcd_com_term_taxonomy
abcd_com_terms
abcd_com_usermeta
abcd_com_users 

Login Issues

We ran into an issue when logging in, where the submit would take the user back to the login screen, with no message as to the reason why.

After digging through the wordpress code and database tables, I found the table abcd_com_options has a column called "option_name" with the value "siteurl" and another column "option_value" with the website's domain name in it. In this case, "option_value" has the value:
http://abcd.com

We had recently added a 301 redirect from abcd.com to www.abcd.com and wordpress uses the siteurl value in their form:
<form id="loginform" action="http://abcd.com/wp-login.php" method="post" name="loginform"></form>

This was the cause of the submit redirecting back to the login screen, from
http://abcd.com/wp-login.php
to
http://www.abcd.com/wp-login.php

After updating the option_value with the domains www version, the form action updated too: 
<form id="loginform" action="http://www.abcd.com/wp-login.php" method="post" name="loginform"></form>

Development Testing

In addition, I was testing this on our development server and I setup the domain dev.abcd.com. In abcd_com_options, I set the value of siteurl to
http://dev.abcd.com/wp-login.php
so it didn't direct the login from our dev to production server.

I realized that wordpress wasn't removing dev from the prefix of the tables, so instead of
abcd_com_options
it was looking for
dev_abcd_com_options

Again, after digging through the Wordpress code, I found in
wp-config.php
where the table prefix was being set, by replacing all periods and dashes with underscores, and www is being stripped out:

$table_prefix = str_replace(".","_",$_SERVER['SERVER_NAME']) . "_";
$table_prefix = str_replace("-","_",$table_prefix);
if(substr($table_prefix, 0, 4) == "www_") $table_prefix = substr($table_prefix, 4, strlen($table_prefix)-4);

To fix my problem, I added the following to work with our development version of the website, which strips out dev, like the above code stripped out www:
if(substr($table_prefix, 0, 4) == "dev_") $table_prefix = substr($table_prefix, 4, strlen($table_prefix)-4);

I was able to test these solutions out on the development server, without the danger of breaking anything else on production. And my solution eventually worked on production as well.

Comments

New Comment