Laravel 9 Automatic Database Encryption Decryption with Eloquent

Apr 30, 2022 . Admin

Hi Artisan,

Today, in this article I will share with you something new about how to automatic data encryption with eloquent in laravel 9 application, i will show an example of how actually encryption and decryption work in a database.by the way laravel 9 provide package elgibor-solution/laravel-database-encryption.

Laravel 9 package that enable eloquent to automatically encrypt data when do preserve and automatically decrypt data when load. Dolefully most of the packages do not fortify search at the encrypted information.

So, how to automatic data encryption with eloquent in laravel 9, database encryption and decryption using elgibor-solution package, database encryption and decryption using elgibor-solution package using laravel 9, automatic data encryption with eloquent in laravel 9 using elgibor-solution package

Here, I will give you a full example of automatic data encryption with eloquent in laravel 9 using elgibor-solution package as below so follow my all steps.

Step 1: Download Laravel

Let us begin the tutorial by installing a new laravel application. if you have already created the project, then skip following step.

composer create-project laravel/laravel example-app
Step 2: Database Configuration

In second step, we will make database Configuration for example database name, username, password etc. So lets open .env file and fill all deatils like as bellow:

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=here your database name
DB_USERNAME=here database username
DB_PASSWORD=here database password
Step 3: Install elgibor-solution package

Via Composer command line:

composer require elgibor-solution/laravel-database-encryption

After successfully install package, open config/app.php file and add service provider.

'providers' => [
    ...
    \ESolution\DBEncryption\Providers\DBEncryptionServiceProvider::class,
],
Step 4: Add In Model

So, In this step i will Use the EncryptedAttribute trait in any Eloquent model that you wish to apply encryption to and define a protected $encrypted array containing a list of the attributes to encrypt.

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use ESolution\DBEncryption\Traits\EncryptedAttribute;

class User extends Authenticatable
{
    use HasFactory, Notifiable, EncryptedAttribute;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The attributes that should be encrypted on save.
     *
     * @var array
     */
    protected $encryptable = [
        'name','email','password'
    ];
}
Step 5: Create Route routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::resource('users', UserController::class);
Step 6: Create Controller

In this step,we will create a UserController.

php artisan make:controller UserController --resource
app/Http/Controllers/UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $users = User::all();

        return view('user.index',compact('users'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('user.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $input = $request->all();
        $validated = $request->validate([
            'name' => 'required|unique:users',
            'email' => 'required',
            'password' => 'required'
         ]);
        
        User::create($input);

        return redirect()->route('users.index');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $users = User::find($id);
        return view('user.edit',compact('users'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $input = $request->all();
        $request->validate([
            'name' => 'required',
        ]);

        $user = User::find($id);
        $user->update($input);

        return redirect()->route('users.index');
    }

}
Step 7: Create a blade view
  • index.blade.php
  • create.blade.php
  • edit.blade.php

In this step, we will create a blade file name index.blade.php bellow following path.

resources/views/user/index.blade.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
    <style type="text/css">
    table.dataTable.no-footer {
        border-bottom: 2px solid #f2f2f2;
    }
    .blog-img {
        width: 200px;
        height: 100px;
        }
    </style>
</head>
<body>

<section class="content mt-5">
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="card">
                    <div class="card-header">
                        <div class="row">
                            <div class="col-md-9">
                                 <h4>Laravel 9 Automatic Data Encryption with Eloquent - <span class="text-primary">MyWebTuts.com</span></h4>
                            </div>
                            <div class="col-md-3 text-right">
                                <a href="{{ route('users.create')}}" class="btn btn-success"><i class="fa fa-plus"></i></a>
                            </div>
                        </div>
                    </div>
                    <div class="card-body">
                        <table class="table table-bordered data-table">
                            <thead>
                                <tr>
                                    <th width="7%">#</th>
                                    <th>Name</th>
                                    <th>Email</th>
                                    <th width="12%">Action</th>
                                </tr>
                            </thead>
                            <tbody>
                        @if(!empty($users) && $users->count())
                            @foreach($users as $key => $value)
                            <tr>
                                <td>{{ ++$key }}</td>
                                <td>{{ $value->name }}</td>
                                <td>{{ $value->email }}</td>
                                <td>
                                    <a href="{{ route('users.edit',$value->id) }}" class="btn btn-primary"><i class="fa fa-pencil"></i></a>
                                </td>
                            </tr>
                            @endforeach
                        @else
                        <tr>
                            <td colspan="4" class="text-center">There are no data found</td>
                        </tr>
                        @endif
                    </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
</body>
</html>

Next following path create a create.blade.php fille

resources/views/user/create.blade.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="content-header mt-5">
      <div class="container">
        <div class="row mb-2">
          <div class="col-sm-6">
            <h4 class="m-0">Create User</h4>
          </div>
          </div>
        </div>
      </div>
    </div>
    <section class="content">
      <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="card">
                    <div class="card-body">
                        @if(count($errors) > 0)
                            <div class="alert alert-danger alert-dismissible">
                                <button type="button" class="close" data-dismiss="alert">×</button>
                                @foreach($errors->all() as $error)
                                    <span>{{ $error }}</span><br>
                                @endforeach
                            </div>
                        @endif
                        <div class="row">
                            <div class="col-md-12">
                                <form action="{{ route('users.store')}}" method="POST" autocomplete="off">
                                    <div class="row">
                                        <div class="col-md-6">
                                            <label for="inputname3">Name:</label>
                                            <div class="form-group">
                                                <input type="text" name="name" placeholder="Enter Name" class="form-control">
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <label for="inputname3">Email:</label>
                                            <div class="form-group">
                                                <input type="email" name="email" placeholder="Enter Email" class="form-control">
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                           <label for="inputname3">Password:</label>
                                            <div class="form-group">
                                                <input type="password" name="password" placeholder="Enter Password" class="form-control">
                                            </div>
                                        </div>
                                    </div>
                                    <div class="box-footer text-center">
                                        <button type="submit" class="btn btn-success btn-flat"><i class="fa fa-floppy-o"></i> Save</button>
                                        <a href="{{ route('users.index') }}" class="btn btn-danger btn-flat"><i class="fa fa-times"></i> Cancel</a>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
      </div>
    </section>
    
</body>
</html>

Next following path create a edit.blade.php fille

resources/views/user/edit.blade.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="content-header mt-5">
      <div class="container">
        <div class="row mb-2">
          <div class="col-sm-6">
            <h4 class="m-0">Edit User</h4>
          </div>
          </div>
        </div>
      </div>
    </div>
    <section class="content">
      <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="card">
                    <div class="card-body">
                        @if(count($errors) > 0)
                            <div class="alert alert-danger alert-dismissible">
                                <button type="button" class="close" data-dismiss="alert">×</button>
                                @foreach($errors->all() as $error)
                                    <span>{{ $error }}</span><br>
                                @endforeach
                            </div>
                        @endif
                        <div class="row">
                            <div class="col-md-12">
                                <form action="{{ route('"users.update",$users->id')}}" method="PATCH" autocomplete="off">
                                    <div class="row">
                                        <div class="col-md-6">
                                            <label for="inputname3">Name:</label>
                                            <div class="form-group">
                                                <input type="text" name="name" placeholder="Enter Name" class="form-control">
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <label for="inputname3">Email:</label>
                                            <div class="form-group">
                                                <input type="email" name="email" placeholder="Enter Email" class="form-control">
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                           <label for="inputname3">Password:</label>
                                            <div class="form-group">
                                                <input type="password" name="password" placeholder="Enter Password" class="form-control">
                                            </div>
                                        </div>
                                    </div>
                                    <div class="box-footer text-center">
                                        <button type="submit" class="btn btn-success btn-flat"><i class="fa fa-floppy-o"></i> Update</button>
                                        <a href="{{ route('users.index') }}" class="btn btn-danger btn-flat"><i class="fa fa-times"></i> Cancel</a>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
      </div>
    </section>
    
</body>
</html>
Step 8: Encrypt your current data

If you have current data in your database you can encrypt it with the command below.

php artisan encryptable:encryptModel 'App\Models\User'

If you have current data in your database you can decrypt it with the command below.

php artisan encryptable:decryptModel 'App\Models\User'

Note: You must implement first the Encryptable trait and set $encryptable attributes

Run Laravel App:

All steps have been done, now you have to type the given command and hit enter to run the laravel app:

php artisan serve

Now, you have to open web browser, type the given URL and view the app output:

http://localhost:8000/users
Output:

Encryptable Data In Database

It will help you...

#Laravel 9