I worked with phalcon and it's amazing. I use ajax for all of my requests. After many updates I had problem with Phalon's built-in CSRF library. I read many topics in phalcon's forum and stackoverflow. None of them helped me much.
As many of you know, if you use Phalcons methods for handling CSRF, there will be a prblem with mutiple windows/tabs.
So I made a solution myself and of course I tried "per session" method. And I also used Phalcon's built-in CSRF library to make token for a session.
I wrote this library:
<?php
namespace Your\Namespace\Library;
/**
* Class TokenManager
*
* @package Your\Namespace\Library
*/
class TokenManager extends \Phalcon\Mvc\User\Component
{
/**
* Generates token per session
*/
public function generateToken($type)
{
$this->session->set('sessionToken' . $type, [
'tokenKey' => $this->security->getTokenKey(),
'tokenValue' => $this->security->getToken()
]);
}
/**
* Checks token given values against session values
*
* @param $tokenKey
* @param $tokenValue
* @return bool
*/
public function checkToken($type, $tokenKey, $tokenValue)
{
if ($this->session->has('sessionToken' . $type)) {
$token = $this->session->get('sessionToken' . $type);
if ($token['tokenKey'] == $tokenKey && $token['tokenValue'] == $tokenValue) {
return true;
}
return false;
}
return false;
}
/**
* Checks if user have token or not
*
* @return bool
*/
public function doesUserHaveToken($type)
{
if ($this->session->has('sessionToken' . $type)) {
return true;
}
return false;
}
/**
* Gets token values from session
*
* @return array|bool
*/
public function getToken($type)
{
if ($this->session->has('sessionToken' . $type)) {
$token = $this->session->get('sessionToken' . $type);
return [
'tokenKey' => $token['tokenKey'],
'tokenValue' => $token['tokenValue']
];
}
return false;
}
}
?>
In controller file I wrote this:
<?php
namespace Your\Namespace\Contollers;
use Your\Namespace\Library\TokenManager;
class SomeController extends \Phalcon\Mvc\Controller
{
public $tokenManager;
public function initialize()
{
$this->tokenManager = new TokenManager();
if (!$this->tokenManager->doesUserHaveToken('User')) {
$this->tokenManager->generateToken('User');
}
//
$this->view->token = $this->tokenManager->getToken('User');
}
public function ajaxAction()
{
if (!$this->request->isPost() || !$this->request->isAjax()) {
$this->response->redirect();
return;
}
if (!$this->tokenManager->checkToken('User', $this->request->getPost('tokenKey'), $this->request->getPost('tokenValue'))) {
// Json Output
return;
}
}
}
For html part:
...
<body>
...
<input type="hidden" id="token" name="{{ token['tokenKey'] }}" value="{{ token['tokenValue'] }}">
</body>
</html>
For js (I use jQuery) and ajax:
$.ajax({
type: 'post',
url: 'path/to/ajax',
dataType: 'json',
data: {
tokenKey: $('#token').attr('name'),
tokenValue: $('#token').attr('value'),
otherData: 'blah blah blah'
}
});
...
Hope its helpfull.