Friday, March 16, 2012

AJAX and Cross Site Request Forgery

One of Yii's features is Cross Site Request Forgery protection. This is mostly transparent and happening automatically if enabled in protected/config/main.php, the relevant option is:

<?php
    //...
    'components'=>array(
        'request'=>array(
            'enableCsrfValidation'=>true,
        ),
    ),
    //...

On each request it then generates a new token which is transparently included in all forms generated by CHtml::beginForm. Checking this token is also handled transparently on submission of these forms.

However, if you are doing AJAX requests, you'll have to pass the token manually. In practice, this is easily overlooked, and leads to irritating bug searches. Since Yii by default uses jQuery and jQuery supports setting default AJAX options, this is how AJAX requests can include the CSRF token automatically (in protected/components/Controller.php):

<?php
class Controller extends CController
{
    public function init()
    {
        $this->initAjaxCsrfToken();
    }
    protected function initAjaxCsrfToken()
    {
        Yii::app()->clientScript->registerScript('AjaxCsrfToken',
        'jQuery.ajaxOptions({data:' . json_encode(array(
            Yii::app()->request->csrfTokenName => Yii::app()->request->csrfToken,
        )) .'});', CClientScript::POS_HEAD);
    }
}

That's it, from now on all AJAX requests done using jQuery include the CSRF token. This includes requests done using $.ajax, $.get, $.post, $.load and others since they all fallback to using $.ajax.

Thursday, March 15, 2012

Sluggable URLs with Catch All

In a previous post I explained a basic approach to make URLs more SEO-friendly. That approach works well if URLs can contain the controller name. But sometimes that's not desirable. What's needed then is a Catch All Route.

Wednesday, March 14, 2012

Slugged URLs

Been working with the Yii Framework for little less than a year now. Something that eventually came up in nearly all projects was SEO-friendly URLs. By default, the URLs Yii generates are already very human readable, but sometimes more is needed, like actually including (urlized) names in the URL. That's commonly called Slugging and the Yii wiki contains a few articles about that. Here is what I have been using.