Does the plugin set the cache control header?
-
Hello there! I found WP (after 6.3) on login (and in wp_login too) sets a Cache Control header. Does the plugin set the same header when the user logs in using the emailed link?
-
Hi @phrasepress,
Thanks for the question!
Yes, when a user logs in via a magic link, they are authenticated through the standard WordPress login process, so WordPress will automatically send the same Cache-Control headers you see after version 6.3.
That said, it would be ideal to include those headers earlier—specifically when the user first clicks the magic link—to prevent any potential caching issues during the login flow. I’m considering adding this natively in the plugin. Thanks for bringing it to my attention!
In the meantime, you can manually enforce the headers like this:
add_action( 'magic_login_handle_login_request', function () { nocache_headers(); } );Let me know if you have any other questions!
This happens before the wp_safe_redirect in LoginManager?
Yes it happens before redirection.
I also confirm that the next update will include the nocache headers – https://github.com/HandyPlugins/magic-login/commit/992fd34f4beb1024ddd68f97bb0e96fadacc1f75
Interesting thread! I tried to manually add that line, but it doesn’t solve the issue I temporarily solved with htaccess the other day. What really surprises me is the traditional login works just fine: why a caching issue is solved by the traditional login and not by the link users receive by email that fundamentally does the same things in another way?
@islp have you tried:
add_action( 'magic_login_handle_login_request', function () { nocache_headers(); } );or just directly modified from plugin source?
@m_uysl Both things! But I must say I did many other things before giving up when I found the htaccess solution (that’s just a temporary patch). Problem with the htaccess is it solves the admin bar issue but it creates an additional Cache Control header for logged in and logged out users: I removed the no-store part and it works anyway, so when you’re logged in basically the broweser doesn’t care too much because the headers added by WP for logged in users are the same I add, so apparently there is no conflict between the two. I’ve had no spare time, so I could not find at least a way to unset the header when the user logs out (I have this header always set, a thing that I don’t like too much. I made a quick test with Apache variables but it didn’t work. I’ll try when I have nothing else to do) 🙂
Another strange fact is the wordpress_logged_in cookie is set when logging in with the link, so really I don’t know what’s going on (I deactiveted anything I could deactivate and tested with incognito, removing cookies, forgetting website, next step is calling an exorcist) 😀
Anyway, I don’t think this is a plugin issue at all, there must be something at some level that prevents the plugin from doing its work, that’s it.-
This reply was modified 7 months, 2 weeks ago by
islp.
Thanks for the details, @islp
Both things!
I suspect the headers might already be sent before
nocache_headers()is called, which would prevent it from adding the expectedCache-Controlheaders. If possible, try enabling the “Preserve log” option in your browser’s dev tools and check the response headers for the magic link request—that might give us more insight.Another strange fact is the wordpress_logged_in plugin is set when logging in with the link, so really I don’t know what’s going on (I deactiveted anything I could deactivate and tested with incognito, removing cookies, forgetting website, next step is calling an exorcist) 😀
Yeah, that part is expected—the behavior mimics a standard login. However, since Magic Login processes the request using the
initaction, it’s possible WordPress is setting those headers earlier in the flow, before we get a chance to override them.-
This reply was modified 7 months, 2 weeks ago by
Mustafa Uysal.
Ok, a couple of tests.
Browser is Firefox (I found the general behavior is the same for Chrome-based browsers too), incognito mode and after erasing any previous trace of the website too (cookies, files, etc).
1.
For this first test, I commented out my rule from the htaccess (this means the user trying to log in with link will NOT see the admin bar: it will appear only if he manually moves to another page).
Load home page (not logged in):
- header Cache Control present, its value is: max-age=2592000 (I suppose this is directly set by the hosting OR is a new WP header for non logged in users);
I move to the login screen:
- header is now Cache Control: no-cache, must-revalidate, max-age=0, no-store, private (this is WP’s)
I request the link, copy it from the mail and paste/enter in the address bar:
- Cache Control header of wp_login is: max-age=2592000
- Cache Control header of the home page (where I redirect_to when I log in from the wp_login screen): max-age=2592000 (and wordpress logged in client cookie is set)
- no admin bar is shown;
If from here I move to any other page, Cache Control changes to: no-cache, must-revalidate, max-age=0, no-store, private and the admin bar is visible.
If I logout, the final Cache Control is max-age=2592000.- For this second test, same browser conditions as above, but I place my rule in the htaccess.
Load home page (not logged in):
- header Cache Control present, this time its value is: no-cache, must-revalidate, private (this is the value set in my htaccess file);
I move to the login screen:
- there are two different Cache Control headers now: no-cache, must-revalidate, max-age=0, no-store, private (WP) and no-cache, must-revalidate, private (htaccess);
I request the link, copy it from the mail and paste/enter in the address bar:
- Cache Control header of wp_login is: no-cache, must-revalidate, private
- Cache Control header of the home page (where I redirect_to when I log in from the wp_login screen): double headers, as above;
- the admin bar is visible;
If from here I move to any other page, Cache Control: double headers as above.
If I logout, the final Cache Control is no-cache, must-revalidate, private (one single header).If you have in mind other tests, let me know (eg. with nocache_headers(), that was not present in the tests here)
@islp thanks for the update.
Could you give a try this:
add_action( 'send_headers', function() { if ( isset( $_GET['magic-login'] ) ) { nocache_headers(); } } );Technically, this shouldn’t make a difference, since the header isn’t set during the init action anyway.
AFAIK, WordPress itself doesn’t set max-age=2592000. It’s likely being added by a plugin or a server-side configuration.
@m_uysl It doesn’t make a difference, as you suggested. As soon as I have some time, I will try to go deeper. 🙂
@m_uysl I found a difference!
In test 1 (so without the htaccess rule), when I log in with link I get Cache-Control: max-age 2592000 (in wp_login AND in the home page, that’s where the user is redirected_to after login);
BUT, if I login with the traditional login screen under the same conditions (no htaccess rule), I get for both pages: Cache-control: no-cache, must-revalidate, max-age=0, no-store, private
So, when using the link, something is preventing the plugin from setting this header properly I suppose AND this only happens when redirect_to value is the home page, because in other cases (when I redirect_to from protected pages) the link works, the wp_login Cache-Control header is this time max-age=2592000 and the final one is again Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private. So maybe this last one is the header really useful, the one after redirection.@m_uysl maybe I found something.
Only for this website I use a membership plugin (WP-Members). The plugin lets you hide content, so that only logged in users can read it. For ten years the plugin duplicated the login screen, providing its own login screen. Last week the website owner asked me to remove this second login screen because users are less and less capable of using websites (according to him) and this double login could confuse them. I removed the second login screen this way:add_filter('template_redirect', function () {
// if the content is blocked by the plugin
if (function_exists('wpmem_is_blocked')) {
if (wpmem_is_blocked() && ! is_user_logged_in()) {
// don't cache headers
nocache_headers();
// redirect the users with the redirect_to in the url
wp_redirect(wp_login_url(get_permalink()));
exit;
}
}
});This thing perfectly works when the redirection is from a protected content (the user finds the protected content, automatically is redirected to the standard login, he logs in and automatically goes back to the previously protected content finding it unprotected).
But, when you login from the standard login screen and redirect_to value is the home page url, some conflict happens with your plugin.
The conflict is eventually “patched” by converting this code to this (for sure not perfect and still untested):add_filter('template_redirect', function () {
if (function_exists('wpmem_is_blocked')) {
if (wpmem_is_blocked() && ! is_user_logged_in()) {
nocache_headers();
wp_redirect(wp_login_url(get_permalink()));
exit;
} else if (!wpmem_is_blocked() && is_front_page()) {
// maybe add !is_user_logged_in
nocache_headers();
}
}
});
Before testing for front page, I tried to GET ‘magic-login’ or check for the referrer but your wp_safe_redirect doesn’t send any referrers.
This “thing” works without editing the htaccess.For sure it lacks other controls and at the moment I have no idea if it could really be the definitive solution (that is: I don’t know if it is efficient and if there are other aspects to consider).
Of course “doesn’t send any referrers” means nothing, I need to sleep more at this point 🤣
-
This reply was modified 7 months, 2 weeks ago by
The topic ‘Does the plugin set the cache control header?’ is closed to new replies.