There are some cases we only need Nginx cache enabled for anonymous users. I can show two ways on how to disable Nginx cache when user is authenticated and enable it for anonymous users in Drupal.
Method 1: Using Cookie
This method invloves Drupal custom module to set an identifier in Cookie that a user is authenticated.
The custom module uses hook_user_login() to set "nocache=1" in Cookie if user is logged in and hook_user_logout() to set "nocache=0" if user is logged out. The codes are as follows (you can download the custom module below this article):
<?php
/**
* Set a cookie for logged in users.
*/
function nginx_nocache_user_login() {
nginx_nocache_user_cookie();
}
/**
* Delete a cookie for logged out users.
*/
function nginx_nocache_user_logout($account) {
nginx_nocache_user_cookie(TRUE);
}
/**
* Helper to set / delete a cookie for users.
*/
function nginx_nocache_user_cookie($delete = FALSE) {
$params = session_get_cookie_params();
if ($delete) {
$expire = REQUEST_TIME - 3600;
$val = 0;
}
else {
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
$val = 1;
}
setcookie('nocache', $val, $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
}
?>
As for our Nginx configuration, we can now tell Nginx if the value "nocache" in Cookie is set disable the cache otherwise enable the cache:
proxy_no_cache $cookie_nocache;
proxy_cache_bypass $cookie_nocache;
Method 2: Using Session
We will only work on Nginx configuration for this method. When a user is logged in we can observe that a session ID is created that is something like this:
SESS35ff8c61bdd320e6efaf605888616911=OteOH_VuieYK9_Y-culzTEsQJevDfIjkUC80d-aO8B
We can use this as identifier if a user is authenticated or anonymous. Our Nginx configuration can have this:
map $http_cookie $no_cache {
default 0;
~SESS 1; # PHP session
}
proxy_no_cache $no_cache;
proxy_cache_bypass $no_cache;
Comments
You're welcome. Remember "if…
You're welcome. Remember "if" is evil. I suggest to use map instead:
map $http_cookie $skip_cache {
default 0;
~SESS 1;
}
thanks!
thanks!
thanks
you saved my life
I have been searching the cookies setting for both proxy cache and fastcgi_cache for a long time.
And finally I can apply this
##dont' cache for logined in users
if ($http_cookie ~* "SESS") {
set $skip_cache 1;
}
which derived from those everywhere tutorial about fastcgi_cache for wordpress.