简体   繁体   中英

Session tokens in PHP being cached by Joomla

I'm using Joomla for a project, and there's some Ajax requests happening to populate data. I generate a Joomla session token in the PHP view, and tack this onto the URL of the Ajax request endpoint, which is also a PHP page, and validates the token before returning data.

Something like this:

// view.html.php
$script = "var ajaxurl = 'index.php?task=ajaxFunction&".JFactory::getSession()->getFormToken()."=1';";
$document->addScriptDeclaration($script);

// ajax.js
var request = new Request.JSON({
    url: ajaxurl,
    onException: function(headerName, value) {
        // etc.
    }
});

// controller
public function ajaxfunction()
{
    JRequest::checkToken('get') or die( 'Invalid Token!' );
    // do other stuff
}

This works just fine until caching is enabled.

The problem is that the view.html.php file, when Joomla uses its internal caching, is cached with the token already set-- so anytime a browser requests the page, it pulls the cached token along with it, meaning the controller will return an invalid Token error.

I know in earlier Joomla builds caching flat out didn't work. Is there a way to make this work in Joomla 2.5+, short of just disabling the Joomla cache? I can't find any way to exclude a single view from caching.

Perhaps you may want to send the request as POST instead of GET, which won't use Joomla caching.

ajax.js

var userToken = document.getElementsByTagName("input")[0].name;

var request   = new Request.JSON({
    url: 'index.php?task=ajaxFunction&'+ userToken +'=1',
    onException: function(headerName, value) {
        // etc.
    }
    onComplete: function(res) {
        // etc.
    }

}).post({});

controller

JRequest::checkToken('get') or die( 'Invalid Token!' );

Stick this at the top of your template file (before all other input tags), it will create a hidden input field containing a token, which will eventually be replaced with the non-cached one on render

tmpl/default.php

<?= JHtml::_('form.token'); ?>

Sometimes I work with Ajax and Joomla and really do not have this problem. Well, maybe the way you is working, is maybe better try a diferent way of do the cache, so if you really have no hope , just fork System - Cache from Joomla, and on your fork make it does not cache what you do not want. If in your project is possible to handle how you do your cache, you can also do not use Joomla Cache and use it with Varnish or similar.

I think it should be better than how you're doing: Joomla have one group to include one more "standard" way to work with AJAX, and you can see one Proof of Concept Here:

Discussion here

Also, another aproach about use of Ajax is here

By looking at the method signature of JSession::getFormToken() you should be able to force a new token by calling getFormToken(true) .

This should circumvent any caching issues you're experiencing.

The way I do it in joomla with a very similar set up is inject the value with JavaScript. The page is cached without the token and JavaScript adds it before making the request

You can pass the value with cookies or another ajax request. Cookies works best fort me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM