Wordpress cookies always expire at the end of the session instead

Despite the fact that I set the cookie expiration date using the auth_cookie_expiration filter in functions.php, none of my login cookies have expiration dates - looking in Chrome the cookies expire at the end of the session. This is true for the wordpress_logged_in and wordpress_sec cookie.

In functions.php, I have the code below. I have also tried a simpler version of the code below. I tried deactivating plugins that are related to logins, and I even grepped auth_cookie_expiration to identify plugins that may be overriding it. De-activating plugins seems to have no effect. I am on a multi-site network, and none of the site cookies have expiration dates.

I don't think it's the code below, because I also tried a much simpler version of the code. What could be causing the issue?

Thank you.

add_filter('auth_cookie_expiration', 'my_expiration_filter', 99, 3);
function my_expiration_filter($seconds, $user_id, $remember){

//if "remember me" is checked;
if ( $remember ) {
//WP defaults to 2 weeks;
$expiration = 14*24*60*60; //UPDATE HERE;
} else {
//WP defaults to 48 hrs/2 days;
$expiration = 2*24*60*60; //UPDATE HERE;
}

//http://en.wikipedia.org/wiki/Year_2038_problem
if ( PHP_INT_MAX - time() < $expiration ) {
//Fix to a little bit earlier!
$expiration = PHP_INT_MAX - time() - 5;
}

return $expiration;
}

  • Adam Czajczyk
    • Support Gorilla

    Hello Alaa

    I hope you're well today and thank you for your question!

    I think there are two aspects of the issue here. First one is the cookie expiration that you're trying to set so let me start with this.

    You're using filter to set expiration and that's fine if you want to affect it. The current code of yours won't change anything in fact because you're using default WP values but the most important part here is the way WP sets cookies.

    If you look into the "wp_set_auth_cookie()" function source code you'll find out that there are actually two variables used: $expiration and $expire. The one that you're changing with the filter and that is the one actually used by WP to determine whether the cookie is expired or not is $expiration. So that's fine.

    However, the one that is set as an actual cookie expiration - the one that you can see in browser - is the other one, the $expire one. You can't change it via filters and there's no need to do it. By default it will be either 0 or to $expiration + 12 hours.

    When it's set to 0 it means that cookie expires when the browser session is ended (which doesn't mean closing browser tab, unless it's an "incognito" mode tab) but browser instance. This is the case when no "remember" option is set. In browser console, depending on the browser, you'll either see no expiration date at all or the date year ahead or something similar.

    When the "remember" option is set, the $expire becomes $expiration + 12 hours and that's what you should then see as expiration date of the cookie. The 12 hours is a "grace period", needed for validation.

    So basically, whatever you set with the filter, you won't see it in browser as expiration date. That value is in fact hashed (together with other information such as user login, a special token and hash) and stored in that hashed form as a cookie value. The function that actually creates cookie value is "wp_generate_auth_cookie()";

    Now, if you didn't use "remember" option, what happens next is (assuming default 2 days cookie expiration):

    - you log in
    - the cookies are set with no expiration date which basically means that the cookie will expire after browser session is closed
    - the full expiration date - encrypted within cookie value - is 2 days
    - if you close browser session before that 2 days, you'll have to login again
    - if you don't close that browser session within 2 days, you'll be automatically logged off after 2 days
    - to validate that WP core does read the cookie from time to time and; if it's expired, the case is simple; if it's not expired it actually compares login data (including expiration) against that hashed cookie value.

    If you chose "remember" option it's pretty similar except the cookie doesn't get removed after browser session is destroyed.

    To sum it up, without using the "remember" option you will see those cookies as having no expiration date (or some distant date like year into the past, that might be different in different browsers). With "remember" option you should see the expiration date as set (+12 hours).

    Now, that being said, it's hard to tell whether your code works but if it doesn't throw any errors, I'd say it most likely does, especially that it's using default values so it doesn't change anything. I'm not sure about the 99 priority and that might be worth experimenting with but basically, it should be fine.

    The question then is: what is the goal here?

    - If it's about only "seeing the expiration value" then I don't think it needs to be addressed at all (as per explanation above).

    - if it's about increasing the login duration above 2 days for users that did not user "remember" function, that should be fine, though you should use longer value than default 2 days; still tho this will not help if the user closes browser entirely and it will not make the cookie expiration (expected expiration show up)

    - if it's about the "remember" option not exactly working as expected - then what is the case: is it that even if you use "remember" you still are not remembered after closing the browser?

    - or is it yet something different that I missed?

    Let me know please and I'll be happy to assist you, I'm pretty sure we can find some solution :slight_smile:

    Best regards,
    Adam

  • Alaa
    • Design Lord, Child of Thor

    Adam, you are a rockstar.

    Prior to posting here, I had read many blog posts about Wordpress cookies. Your explanation by far is the most complete, and authoritative.

    I didn't realize the expiration date would only be set if "remember me" was checked.

    My original issue was that even if the "remember me" checkbox was checked, when someone rebooted their computer or closed their browser session, they would have to log back in. In addition, if someone was logged in at a computer, and they logged in on a phone, it would log them off on the computer.

    I deactivated and re-activated some plugins, and took my .htaccess file back to a clean state, - I removed entries inserted by WPRocket, and it seems like the issue has gone away.

    Your explanation, made me realize I was testing incorrectly, so again - thank you.

    I do have another question that is related... I would like to default the remember me checkbox to checked. I am using the login-with-ajax plugin. My login form is here: https://mnet2.marianilandscape.com/expense/

    The plugin gives you a way to override the standard widget, and my override code is below. Do you know how I would modify it so that "remember me" would default as checked?

    Again, many thanks!

  • Alaa
    • Design Lord, Child of Thor

    I forgot to include the override template:

    <?php
    /*
     * This is the page users will see logged in.
     * You can edit this, but for upgrade safety you should copy and modify this file into your template folder.
     * The location from within your template folder is plugins/login-with-ajax/ (create these directories if they don't exist)
    */
    ?>
    <div class="lwa">
    	<?php
    		global $current_user;
    		get_currentuserinfo();
    	?>
    	<span class="lwa-title-sub" style="display:none"><?php echo __( 'Hi', 'login-with-ajax' ) . " " . $current_user->display_name  ?></span>
    	<table>
    		<tr>
    			<td class="lwa-info">
    				<?php
    					//Admin URL
    					if ( $lwa_data['profile_link'] == '1' ) {
    						if( function_exists('bp_loggedin_user_link') ){
    							?>
    							<a href="<?php bp_loggedin_user_link(); ?>"><?php esc_html_e('Profile','login-with-ajax') ?></a><br/>
    							<?php
    						}else{
    							?>
    							<a href="<?php echo trailingslashit(get_admin_url()); ?>profile.php"><?php esc_html_e('Profile','login-with-ajax') ?></a><br/>
    							<?php
    						}
    					}
    					//Logout URL
    					?>
    					<a id="wp-logout" href="<?php echo wp_logout_url() ?>"><?php esc_html_e( 'Log Out' ,'login-with-ajax') ?></a><br />
    					<?php
    					//Blog Admin
    					if( current_user_can('list_users') ) {
    						?>
    						<a href="<?php echo get_admin_url(); ?>"><?php esc_html_e("blog admin", 'login-with-ajax'); ?></a>
    						<?php
    					}
    				?>
    			</td>
    		</tr>
    	</table>
    </div>
  • Adam Czajczyk
    • Support Gorilla

    Hi Alaa

    Thanks for your response!

    I deactivated and re-activated some plugins, and took my .htaccess file back to a clean state, - I removed entries inserted by WPRocket, and it seems like the issue has gone away.

    Yes, plugins that either do some "heavy optimization" or, first of all, some complex caching might sometimes affect the way cookies are handled. I'm glad that you found the culprit :slight_smile:

    As for the "remember me". The code that you shared doesn't seem to be related as it seems to affect only already logged in users so the "remember me" checkbox doesn't apply in such case. I'm not familiar with this plugin and I'm not sure if/how we could properly hook to its code or alter its templates but I see that someone (I believe it was you) already asked plugin developer on wordpress.org forum. So I hope you'd be able to get a better answer there.

    Meanwhile I think I can provide you with a bit "hacky" workaround based on JS. We can simply force the checkbox to be checked with JS upon the page load and while not very "elegant" it should work for now.

    To give it a try, follow these steps:

    1. create an empty file with a .php extension (e.g. "ajax-login-remember-me-check.php")
    2. copy and past this code into it:

    <?
    function wpmu_ajax_login_remember_me_default() {
        ?>
        <script type="text/javascript">
    	jQuery(function($) {
    
    	     $('.lwa-rememberme').prop('checked', true);
    
        });
    	 </script>
        <?php
    }
    add_action('wp_footer', 'wpmu_ajax_login_remember_me_default');

    3. save and upload the file to the "/wp-content/mu-plugins" folder of your WP install; if there's no "mu-plugins" folder there, just create an empty one first.

    Please note: I only tested the JS code via browser so in case it wasn't working or was breaking the site, first remove the file from /wp-content/mu-plugins folder (it will bring the site back to as it is now) and then let me know here and I'll look into it again.

    Best regards,
    Adam

  • Alaa
    • Design Lord, Child of Thor

    Adam, you really have gone above and beyond!

    I created the php file in the mu-plugins directory, but I got the white screen of death as if there was a syntax error? Below is what I pasted in, I went to the site, got the white screen, and then renamed the php file to php2 and it went away...

    Any thoughts?

    Thank you again!

    <?
    function wpmu_ajax_login_remember_me_default() {
        ?>
        <script type="text/javascript">
    	jQuery(function($) {
    
    	     $('.lwa-rememberme').prop('checked', true);
    
        });
    	 </script>
        <?php
    }
    add_action('wp_footer', 'wpmu_ajax_login_remember_me_default');
  • Adam Czajczyk
    • Support Gorilla

    Hi Alaa

    I have just tested it on my end and it seems to be working fine: I've installed the plugin, added a login widget to the sidebar and put that code on site as mu-plugin (exact code that you have posted above). There was no errors of any kind reported and the "remember me" checkbox was checked as expected.

    I'm not quite sure then what is causing this. It doesn't seem to be a syntax error but maybe it's some some conflict then? On my end, I tested it on a very basic install - nothing but the Login with Ajax plugin, my code and Twenty Nineteen theme - so it might behave differently on your end. It shouldn't as the code is very simple but we can't rule out anything just yet.

    Taking that into account, could you please do one more test? That should, hopefully, tell us what is causing the "white screen" issue:

    1. Enable debugging in WordPress by adding following lines to the "wp-config.php" file, right above the "/* That's all, stop editing! */ line:

    define( 'WP_DEBUG', true);
    define( 'WP_DEBUG_DISPLAY', false);
    define( 'WP_DEBUG_LOG', true);

    2. add the code (mu-plugin) again and load the site so the "white screen" would happen; try triggering that issue 2-3 times in a row, just in case.

    3. remove the code so the site was running fine again and look into the /wp-content folder of the server; there should be a "debug.log" file created so please share the file or its content (if it's not too long) with me here.

    To attach the file here you'd need to rename it to debug.txt first but if it's too big and doesn't go through, please upload it to some file storage of yours (Google Drive, Dropbox or similar) and just share a direct download link with me.

    This should, hopefully, show us what's going wrong :slight_smile:

    Best regards,
    Adam

  • Alaa
    • Design Lord, Child of Thor

    Thank you for your diligence with this, and again for going above and beyond by loading the plugin, and performing your tests. I really do appreciate it.

    I did the steps above, and although there were many lines repeated in the debug log, I deleted all but the unique ones. I think the line we are looking for is the second one below.

    `[19-Feb-2019 13:02:52 UTC] PHP Notice: attribute_escape is deprecated since version 2.8.0! Use esc_attr() instead. in /var/www/vhosts/marianilandscape.com/httpdocs/wp-includes/functions.php on line 3923
    [19-Feb-2019 13:03:19 UTC] PHP Parse error: syntax error, unexpected '}', expecting end of file in /var/www/vhosts/marianilandscape.com/httpdocs/wp-content/mu-plugins/ajax-login-remember-me-check.php on line 12'

  • Adam Czajczyk
    • Support Gorilla

    Hi Alaa

    Hm... that's strange. That is the syntax error then but I can't say why: the code posted here (both mind and the one that you re-posted) looks fine and I explicitly tested it on my end - I literally copied the code from you post, no errors.

    But I'm sure it's something very simple though I'd need to take a look. Could you enable support access to the site (by going to the "WPMU DEV -> Support" page in your site's back-end and clicking on "Grant support access") and then also share either cPanel (preferably) or FTP access with me?

    Note: please do not post any access credentials here. Instead, once you enable support access, simply post access information in the text box right below the "Access active for X days" on the "WPMU DEV -> Support" page. This way the information will stay within your site and remain confidential.

    Just let me know when it's done and I'll take care of this, I'm sure we can sort it out in no time :slight_smile:

    Best regards,
    Adam

  • Adam Czajczyk
    • Support Gorilla

    Hi Alaa

    Thank you for enabling access.

    My current IP is 83.9.251.230 so let's give it a try.

    However, it's not a static IP and I have no way of knowing for how long it will remain assigned to me. In fact, most of staff here are using dynamic IP and/or are working from different locations over time. We're globally distributed company working all around the globe so when dealing with support (unless it's an issue that requires no access to the site at all) it's very important to make sure that the site itself (front-end) and FTP/cPanel access - if necessary - are made available without restrictions (at lest temporarily, for the time of support assistance). That's just for future reference though :slight_smile:

    Let me know once you white-listed that IP and put the credentials in the "Network Admin -> WPMU DEV -> Support" page text box and hopefully it will work. Alternatively, maybe you got some sort of cPanel or similar panel (with some kind of "file manager" tool there) that'd be available without such restrictions? If yes, please put credentials information in the same place.

    Let me know here once it's done as I don't get any notifications of any messages posted in that box within your site - so I'll only see them after accessing your site.

    Best regards,
    Adam

  • Alaa
    • Design Lord, Child of Thor

    Hi Adam,

    I did a little bit of research and digging, and I was able to get a slightly modified version of your code to work for me. This is the final version:

    <?php
    function wpmu_ajax_login_remember_me_default() {
        ?>
        <script type="text/javascript">
    	jQuery(function($) {
    
    	     $('.lwa-rememberme').prop('checked', true);
    
        });
    	 </script>
        <?php
    }
    add_action('wp_footer', 'wpmu_ajax_login_remember_me_default');
    ?>

    I saw this link: http://php.net/manual/en/language.basic-syntax.phptags.php

    Which talked about using <?php instead of <?. I'm not sure if it mattered or not, but I used a closing ?> tag at the end.

    Thank you again soooo much for going above and beyond. You truly have been a pleasure to interact with.

  • Adam Czajczyk
    • Support Gorilla

    Hi Alaa

    Aaahhh... right, the php opening tag! I admit I didn't even notice it and, to be honest, I'm not even sure why I did use the "short tag" instead of "full" one - I always use the full one.

    Sorry about that and I'm glad you solved that. Thanks for letting me know and thanks for your kind words!

    Have a great day,
    Adam

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.