Url Id Encrypt/decrypte

Hi Yii experts,

Since i am new to Yii framework ,i would like to request help from Yii experts.

Currently i facing issue with URL id encode/decode.

Such as

from http://www.website.com/view/id/10

to

http://www.website.com/view/id/uUG32376HJBDwg2366Gh_308

What i did so far i create a encrypt class for that id and yes its can able to encypt the id such as per shown above.but when i click the view option the controller view action throw error such as Page not found 400 error.

im pretty sure it because of the url manager configuration in the main.config file.but i dont know how to solve this issue.

Then i found the Yii got solution for it by using the CbaseURL.

The question is how to use this.Is it i need to define function for each of the pages path or just only one.

‘rules’ => array(

‘’ => ‘site/index’, // normal URL rules

array( // your custom URL handler

'class' => 'application.components.CustomUrlRule',

),

),

class CustomUrlRule extends CBaseUrlRule {

public function createUrl($manager,$route,$params,$ampersand) {

return your_encrypt_method($route);

}

public function parseUrl($manager,$request,$pathInfo,$rawPathInfo) {

return your_decrypt_method($pathInfo);

}

}

Hi Vinoth,

I do not really know whether I understand you correctly, but you might want to

add the rule


'<controller:\w+>/<action:\w+>/<id:[\-]?\d+>'=>'<controller>/<action>',

Normally id is set as <id:\d+> wherefore it only accepts integers, or \w+ for letters.

However, you have to look for the right regular expression for your id.

Then you can call the decryption function from the Controller action. There you receive e.g. $id;

$realId = $this->decryptUrlId($id);

Where decrypteUrlId is located in the same model where the id is encrypted.

Please let me know if this provides you with more information/insights.

I would think just changing <id:[\-]?\d+> to <id:[\-]?\w+> would work. As FOX says, just decrypt the id as the first step in the action.

Hi Fox & Jkofsky,

Thank for your reply.

I did as per mention by Fox but trick didnt work as well.but Jkofsky trick was works as well by changing this

<id:[\-]?\d+> to <id:[\-]?\w+>. Then the rest i did as per FOx mentioned earlier by changing the id encryption in controller action method.

BUT now the issue is ,its not working for all other encrypted id and only working for certain encrypted id.

such as :

When i try to access this below url no issue at all.able to view the data.

a.)http://localhost/workspace2/yii/organisation/view/TXgcClNtqaJUozJoRNoGn6MOnBpVI3j3KuTzMfI_AAY

b.)http://localhost/workspace2/yii/organisation/view/y77aSykIATYWJDC64QFROfMuXoJG84e2TCjho9lwJAY

for the below url i cant view the data ,its throw this error :Error 400 Your request is invalid.

c.)http://localhost/workspace2/yii/organisation/view/ydNCaNB-9suxDEqD4qWDCsrAZO_yWvHboX1hqKZk2gw

d.)http://localhost/workspace2/yii/organisation/view/6icsR7MPn2pRBpJLLmG4eNZ1ZKFH4m-561zpxvMAdVU

Controller View




	/**

	 * Displays a particular model.

	 * @param integer $id the ID of the model to be displayed

	 */

	public function actionView($id)

	{

		$id = EncrptionUrl::decode($id);

		$model2 = new Contactperson('searchOrganisation');//contact person

		$model2->unsetAttributes();  // clear any default values

		if(isset($_GET['Contactperson'])){

		    $model2->attributes = $_GET['Contactperson'];

		}

		$this->render('view',array(

			'model'=>$this->loadModel($id),'model2'=>$model2

		));

	}



Main.config




	// uncomment the following to enable URLs in path-format

		//Hide the index.php to secure shorter URL path

		'urlManager'=>array(

		    'urlFormat'=>'path',

			'showScriptName'=>false,

	 	//	'caseSensitive'=>false,    

			  

	 		//'urlSuffix'=>'.html',  

		   'rules'=>array(

  		        '<controller:\w+>/<id:\d+>'=>'<controller>/<action>',

			//	'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

				'<controller:\w+>/<action:\w+>/<id:[\-]?\w+>'=>'<controller>/<action>',

				'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

				),

		),

			



EncrptionUrl class file.





class EncrptionUrl {

	//private static $skey 	= ''; // you can change it 32 chars

	

	public  function safe_b64encode($string) {

        $data = base64_encode($string);

        $data = str_replace(array('+','/','='),array('-','_',''),$data);

        return $data;

    }


	public function safe_b64decode($string) {

        $data = str_replace(array('-','_'),array('+','/'),$string);

        $mod4 = strlen($data) % 4;

        if ($mod4) {

            $data .= substr('====', $mod4);

        }

        return base64_decode($data);

    }

	

    public static function encode($value){ 

		

		$skey = Yii::app()->params['encrypt_url_pathid'];

	    if(!$value){return false;}

        $text = $value;

        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $skey, $text, MCRYPT_MODE_ECB, $iv);

        return trim(EncrptionUrl::safe_b64encode($crypttext)); 

    }

    

    public static function decode($value){

		$skey = Yii::app()->params['encrypt_url_pathid'];

		if(!$value){return false;}

        $crypttext = EncrptionUrl::safe_b64decode($value); 

        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $skey, $crypttext, MCRYPT_MODE_ECB, $iv);

        return trim($decrypttext);

    }



Hi Vinoth,

The regular expression you used implies the following:

\d [0-9], so all digits

\w [a-zA-Z0-9], including all characters and numbers

[See link]

What you require in your url encryption is including the _ and -.

Both links that do not work, contain a ‘-’. So to make it work

you should change the code towards:


'<controller:\w+>/<action:\w+>/<id:[a-zA-Z0-9_-]+>'=>'<controller>/<action>',

Please note, I’ve not tested the code yet, but my assumption is that this should work.

Perhaps you should include a \ before the -


'<controller:\w+>/<action:\w+>/<id:[a-zA-Z0-9_\-]+>'=>'<controller>/<action>',

Hope this helps.

With kind regards,

Reinier

Hi Fox,

Thanks a lot its working finally!

Firstly i am did insert these symbols -> "_" & "-".

the rule was like this before ->’<controller:\w+>/<action:\w+>/<id:[\_-]?\w+>’=>’<controller>/<action>’,

but unfortunately it didn’t work.

But your suggestion by using regex allowing the alphanumeric plus the symbols help to solve the problem.

so in the future i jst need to modify the regex according to the encryption characters.

Thanks again bro!

Dear Vinoth,

Great that it worked!

Your modification


<id:[\_-]?\w+>

allowed every ID that start with zero or one occurrence of a ‘_’ or ‘-’. Since there is no shortcut (like \w) which includes punctuation, it suits better to create a regular expression yourself which fits only the possible options. Hence, if someone uses a “$” or “’” to hack the system or something this will result in a ‘failure of the url’.

Perhaps it is nice to look at this tutorial.

Good luck with the rest of your system!