I'm building a custom Joomla component and I added this to my form in my template (default.php) file (it is using a HTTP POST):
echo JHTML::_( 'form.token' ); //add hidden token field to prevent CSRF vulnerability
Then I check the token in my controller with:
JRequest::checkToken() or die( 'Invalid Token' );
But no matter what I do I get an Invalid Token. I have verified that a hidden type with a token is created in my form when I view sources on the html page. I also verified, in the controller, the value of the token is the same:
print_r(JUtility::getToken());
So if the token is the same value, why on earth is it exiting with an Invalid Token message?
EDIT: There is a key piece I failed to mention. My form is processed with jquery ajax in a separate js file that is added in my view.html.php. This is what the ajax POST looks like:
jQuery.ajax({
type: 'POST',
url: 'index.php?option=com_recordings&task=deletevideos&format=raw',
data: {checkedarray:checked},
success: function(data){
//delete row
}
});
The controller processes this:
function deletevideos()
{
$video_list = JRequest::getVar('checkedarray', 0, 'post', 'array');
//print_r(JUtility::getToken());
JRequest::checkToken() or jexit( 'Invalid Token' );
$model = &$this->getModel();
return $model->setDeleteVideos($video_list);
}
This then goes to the model that does the DB update. I saw this old post that might be relevant. It is not clear to me how/where I generate the token and where/how I validate that token. The post seems quite involved as it checks against users as well which I don't think is needed in my case. Or maybe I misunderstand?
EDIT #2
Okay so the token is missing and I need to pass it into my js file. So I thought I could add this to my view.html.php:
$addtoken = JUtility::getToken();
$addtokenjs = 'jQuery(function() {
var token="'.$addtoken.'";
});';
$doc->addScriptDeclaration( $addtokenjs );
$doc->addScript(JURI::base()."components/com_recordings/js/recordings.js");
I have to put this in the document ready function because apparently addScriptDeclaration does not put anything ahead of my recordings.js file. Then pass the token into the ajax
call:
jQuery.ajax({
type: 'POST',
url: 'index.php?option=com_recordings&task=deletevideos&format=raw'+token+'=1',
data: {checkedarray:checked},
success: function(data){
//delete row
}
});
Apparently I'm not doing this right as I get this error: ReferenceError: token is not defined
.
The obvious problem with your initial code is that you are not passing the token to the controller.
data: {checkedarray:checked}
probably contains just an array of IDs you want to delete.Irfan version is the easiest to implement and it should work. I've managed to make it work.
Here is a gist with the working code (please note that this is not production ready code, it's just to test the token problem). But I've tested it and it works for me.
It does not seem that you are passing token value in the ajax request.And that's why you are getting this error.
You can - 1) append token to the url like this
2) Or send the whole form using Serialize.
EDIT 2:- You can create a function called getToken like this-
And in url instead of calling
token
you can callgetToken()
Hope this will work.
Just in case of future use: On Joomla! 3.x
JUtility::getToken()
has been replaced withJSession::getFormToken()
.See here: http://api.joomla.org/cms-3/classes/JSession.html#method_getFormToken
Try using
rather than JRequest. The reason I like JSession more is because it guarentees Joomla 2.5/3.0 compatibility without having to think about JRequest being deprecated. In Joomla 2.5 the function uses JRequest and in 3.0 uses JInput.
EDIT
For the AJAX ou actually need to pass the data across with the
POST
. Your data is currently just going to be thecheckedarray:checked
i.e. the checked data and NOT the token in the AJAX request. You'll need to pass the data across with serialize if you wish to use thePOST
method. However note that serialize will place the data in the URL anyhow. You can then process this token withJust for completelness the link you have given uses the GET method. In that he's passed across the username (in his case) and the token in the URL as you can see on the third line of his AJAX function
and then after this is it is trivial to process just using
Either way its probably going to involve some tweaking to your model - as your passing across more than 1 variable - although it shouldn't be hard to do. Hope this helps!
If the form data is submitted as
$_GET
If the form data is submitted as
$_POST
Else you can use below which is preferred
Read more