Since Joomla! 1.5.3, a security feature has been added to the Joomla! CMS which checks submitted forms for the existance of a specific token.
If it does not exist, the form is considered as spam or even a hack-attempt, and an error-message Invalid token is displayed on the screen. Sometimes regular users will see such an error. Recently I had to troubleshoot such an instance - the culprit was caching.
Invalid token after a session timeout
If you load a Joomla! webpage in your browser, the HTML of that webpage is fetched from the Joomla! webserver and in most cases Joomla! will also keep track of your activities by using a session. For instance if you login, a new session is started - which is very important because otherwise Joomla! can't tell if you are the same person that logged in previously.
If you load a Joomla! webpage that uses a form, the same applies. But now inside the form an extra hidden field is added - the so-called token. This token makes sure that the submitted values you send back from your browser to Joomla!, match the form sent from Joomla! to your browser. The token however is related to the session.
So if your session times out, the token will timeout. Say you requested a login-page but then left for a long lunch: After you come back from lunch you should refresh the page, before attempting to login. If you submit the form without this refresh, the session will have timed out, resulting in an Invalid Token page.
Invalid token because of caching
In the previous paragraph you have read that if a form is displayed for a too long time, the session will expire and the token will become invalid. The same problem applies when the HTML of the form does not change anymore - and this is mainly caused by caching.
There are two types of caching in Joomla! (at least those are the two you have to deal with as Joomla! administrator): Page caching and per-extension caching. The last one is equal to the caching-option found in the Global Configuration (under the tab System). If you turn the cache on, this will enable caching for all extensions that allow for caching.
Some times caching is the perfect way to gain performance. If you use a lot of Content Plugins that modify the content of various articles, caching the articles after the plugins have done their work may improve performance a lot. Many modules also allow for caching, while with many of them caching can be disabled by modifying the modules parameters.
Never cache a form
Take for instance the Login Module (mod_login). This module shows a small login-form on the page, but like every other form this form contains a token. If the token would be cached, the token will not change anymore with every refresh of the browser, which will make the token (thus the entire form) unusable. The login-module therefor offers a parameter Cache which can only be set the Disabled. If you turn on caching in the Global Configuration, it will never apply to the login-module. This makes sure the login-module can always function properly.
In general, all forms that contain a token (and all forms should contain a token), should not be cached. Page Caching is therefor far more dangerous. This feature is tucked away as a System Plugin, which is disabled by default. Instead of caching bits and pieces on every page, the entire page is cached at once. If you have a pretty static website, this will do no harm. But if your website contains forms and those forms contain tokens, Page Caching will automatically cache those tokens together with the complete page. This is why the System - Cache Plugin should only be enabled in rare circumstances.
mod_login is still cached?
That said, I ran into a strange problem where the Login Module form caused Invalid Token warnings when caching was enabled. But the Login Module itself had obviously the setting Cache disabled - there is no other option. After inspecting the HTML-source I concluded that indeed the token remained the same after every browser-refresh, so somewhere the module output had to be cached. When turning off caching in the Global Configuration, the problem disappeared, so the problem was related to Joomla!.
Now, Joomla! has a nice little feature that allows you to define module positions inside content. It is one of the more complex features, because it requires a sound understanding of plugins, modules, module position and how plugins can modify content. Here it is: There is a plugin called Load Module, which allows for certain tags to be replaced with actual modules. The plugin can be enabled in the Plugin Manager.
As soon as this plugin is enabled, it will search in the article text for a string like {loadposition user1} which tells the plugin to replace that string with the output of all modules on position user1. Let's say we have a Login Module instance that is configured on position user1, than we can use the Load Module plugin to display the Login Module inside an article text.
But if caching is enabled, the Login Module form is rendered inside the article and after that, the article is cached. So while caching is a wonderfull thing, using form-modules inside articles is generally a bad idea.
Some form components like RSForms allow you to add a form to an article easily, while other plugins allow for component output in articles. The same problem applies. It is generally a bad idea to insert forms into articles - it's not what they're ment for.
1 comment:
Thanks for sharing your article,it’s very nice,thanks.I hope can read more good articles.
joomla extension
Post a Comment