When our web app contain ID in plain number will allow visitor to browse data of other records. Say you have www.example.com/certificates/view.html?id=234. In this case visitor could see record with id of 233, 235, 236 and so on with just change directly in the browser. It will impossible to do the above if we change the with encripted one, such as id=ghfyt== or id= rtyrtrh.
This tutorial will help you to obscure the id in our yii2 web app.
There will be 4 steps:
- create encription/decription functions in the componen folder
- change main/config
- encript the id
- decription the encripted id.
In this example I use advanced template. If you use basic template should adjust it.
- Create Encription/Decription Functions
First create new folder in our frontend directory if we do not have it before. After the folder creation your frontend folder will look like:
frontend
—assets
—components
—config
—controllers
—models
—runtime
—tests
—views
—web
Then create a file in the component folder with any name, in my case I give it GenerikComponent.php and type in the file the following code:
namespace frontend\components;
use yii\helpers\Html;
use yii\base\component;
class GenerikComponent extends Component{
public function enkrip($id){
$ciphering = "AES-128-CTR";
$options = 0;
$encryption_iv = '1234567891011121';
$encryption_key = "ANY_KEY_OF_YOUR_CHOICE";
$this->encrypted = openssl_encrypt($id, $ciphering, $encryption_key, $options, $encryption_iv);
return $this->encrypted;
}
public function dekrip($id){
//jenis cipher yg digunakan
$ciphering = "AES-128-CTR";
$options = 0;
// Non-NULL Initialization Vector for decryption
$decryption_iv = '1234567891011121';
$decryption_key = "ANY_KEY_OF_YOUR_CHOICE";
$this->decrypted = openssl_decrypt ($id, $ciphering, $decryption_key, $options, $decryption_iv);
return $this->decrypted;
}
}
I ve created two functions with name enkrip dan dekrip in the file.
- Modify main/config.php file
Just amend it with the following code:
'components' => [
.....
'generik' => [
'class' => 'frontend\components\GenerikComponent',
],
...
]
- Encript any ID
Now we can implement our encription function in any part of our app.
a. View,
The simplest one below is my code in index file:
GridView::widget([
'dataProvider' => $dataProvider,
'summary'=>'',
'filterModel' => $searchModel,
'columns' => [
[
'class' => 'yii\grid\SerialColumn',
'headerOptions' => ['style' => 'width:3%', 'class' => 'text-left'],
],
....
....
[
// 'attribute' => 'certificate_id',
'label' => 'Certificate#',
'headerOptions' => ['style' => 'width:5%', 'class' => 'text-center'],
'contentOptions' => ['style' => 'width:5%', 'class' => 'text-center'],
'format' => 'raw',
'value' => function ($model) {
$id = Yii::$app->generik->enkrip($model->id);
return Html::a($model->id, ['/certificates/view','id'=>$id]);
},
],
....
We could see in the above $id = Yii::$app->generik->enkrip($model->id) in this code Yii::$app->generik->enkrip() is call function enkrip in the componen generik.
b. Any other place
Of course we could implement our enkrip component in any other place such in controller. We just call it by calling Yii::$app->generik->enkrip(ANY_ID_OR_STRING). And use the dekrip function to see the encripted string into plain string.
If we call the address in the browser will look like example.com/certificates/view.html?id=rfdsu== and when we click it we will get 404 Error Not Found message. It caused by the ID is not known by our action view in the controller. We have to modify it.
- Decript actionView Controller.
Go to your controller then modify actionView like this:
public function actionView($id)
{
$id = Yii::$app->generik->dekrip($id);
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
We just add one line $id = Yii::$app->generik->dekrip($id), it will convert our previous encripted ID into plain ID.
Now you can try again in your browser, should be display our data as usual.
That’s it. Good luck.