Menambahkan Jejak Audit Realtime Laravel Menggunakan Pusher - CRUDPRO

Menambahkan Jejak Audit Realtime Laravel Menggunakan Pusher

Jejak audit adalah catatan semua perubahan yang dibuat pada model data. Model adalah entitas apa pun yang dapat disimpan dalam database, seperti pengguna atau produk. Entri audit biasanya berisi informasi tentang jenis perubahan (dibuat, diperbarui, atau dihapus), siapa yang membuat perubahan, dan kapan perubahan itu dilakukan. Jejak audit sering digunakan dalam aplikasi besar di mana perubahan pada satu atau lebih model perlu dilacak dari waktu ke waktu.

Dalam tutorial ini, kami akan menyiapkan dasbor jejak audit yang dapat diakses administrator untuk aplikasi stok sederhana. Dasbor diperbarui secara real time sehingga Anda dapat melihat kapan pembaruan terjadi. Berikut adalah pratinjau dari aplikasi yang sedang berjalan:

Prasyarat

  • PHP 7.1.3. atau lebih baru
  • Komposisi
  • Akun pendorong. Buat di sini.

Pengaturan

Mari kita mulai dengan aplikasi stok kecil yang saya buat. Anda dapat mengkloning proyek Anda dari GitHub dengan menjalankan perintah berikut:

git clone https://github.com/shalvah/stockt.git
 
Anda juga dapat mengunduh sumber langsung dari tautan ini. Kemudian cd ke folder proyek untuk menginstal dependensi.
composer install

Kemudian salin .env.example ke file baru bernama .env. Jalankan perintah berikut untuk menghasilkan kunci enkripsi aplikasi.

php artisan key:generate

Terakhir, buat file bernama database.sqlite di direktori database Anda dan jalankan perintah berikut untuk mengatur database Anda dan memasukkan data Anda.

php artisan migrate --seed

Membuat dasboard audit

Gunakan paket laravel-auditing untuk menangani audit. Mari kita instal paketnya:

composer require owen-it/laravel-auditing
Kemudian publikasikan dan jalankan migrasi database dari tabel audit.
php artisan auditing:install
php artisan migrate

Mengaudit perubahan produk. Konfigurasikan model product Anda sehingga paket audit Anda dapat dilacak. Model product ('app/Models/Product.php'):

  • menggunakan OwenIt\Auditing\Auditable trait
  • menerapkan OwenIt\Auditing\Contracts\Auditable interface:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;

class Product extends Model implements Auditable
{
  use \OwenIt\Auditing\Auditable;

  // ...
}
Sekarang, setiap kali perubahan dilakukan pada produk, detail perubahan dicatat dalam tabel audit.

Perubahan kecil perlu dilakukan pada konfigurasi audit sehingga model audit dapat dipetakan dengan benar ke model user. Ini memungkinkan Anda untuk menulis kode seperti $audit→user→name untuk mendapatkan nama pengguna yang melakukan perubahan. Pada file config/audit.php, ganti nilai model di array pengguna dengan nama kelas model user (App\Models\User::class).

'user' => [
  'primary_key' => 'id',
  'foreign_key' => 'user_id',
    
  // replace the line below
  'model'       => App\User::class,
    
  // with this
  'model'       => App\Models\User::class,
],

Kemudian lanjutkan ke dasbor audit. Pertama, buat middleware yang hanya dapat dilihat oleh pengguna admin. Buat file bernama AllowOnlyAdmin.php di app/Http/Middleware dengan konten berikut.

<?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Support\Facades\Auth;
    
    class AllowOnlyAdmin
    {
        public function handle($request, Closure $next)
        {
            if (Auth::user()->is_admin) {
                return $next($request);
            }
            
            abort(403);
        }
    }

Kemudian tambahkan route audit ke akhir routes/web.php

Route::get('audits', 'AuditController@index')
->middleware('auth', \App\Http\Middleware\AllowOnlyAdmin::class);

Mari kita buat controller. kemudian akan mengenerate file app/Http/Controllers/AuditController.php , dengan melakukan perintah:

php artisan make:controller AuditController
Buat metode index di kelas AuditController dengan konten berikut:
public function index()
{
    $audits = \OwenIt\Auditing\Models\Audit::with('user')
        ->orderBy('created_at', 'desc')->get();
    return view('audits', ['audits' => $audits]);
}

Mari kita buat tampilan audit. Buat file resources/views/audits.blade.php dengan isi sebagai berikut:

@extends('layouts.app')
    
    @section('content')
      <div class="container">
        <table class="table" >
          <thead class="thead-dark">
            <tr>
              <th scope="col">Model</th>
              <th scope="col">Action</th>
              <th scope="col">User</th>
              <th scope="col">Time</th>
              <th scope="col">Old Values</th>
              <th scope="col">New Values</th>
            </tr>
          </thead>
          <tbody id="audits">
            @foreach($audits as $audit)
              <tr>
                <td>{{ $audit->auditable_type }} (id: {{ $audit->auditable_id }})</td>
                <td>{{ $audit->event }}</td>
                <td>{{ $audit->user->name }}</td>
                <td>{{ $audit->created_at }}</td>
                <td>
                  <table class="table">
                    @foreach($audit->old_values as $attribute => $value)
                      <tr>
                        <td><b>{{ $attribute }}</b></td>
                        <td>{{ $value }}</td>
                      </tr>
                    @endforeach
                  </table>
                </td>
                <td>
                  <table class="table">
                    @foreach($audit->new_values as $attribute => $value)
                      <tr>
                        <td><b>{{ $attribute }}</b></td>
                        <td>{{ $value }}</td>
                      </tr>
                    @endforeach
                  </table>
                </td>
              </tr>
            @endforeach
          </tbody>
        </table>
    
      </div>
    @endsection
Anda dapat meluncurkan aplikasi dengan menjalankan perintah berikut:
php artisan serve

Lalu buka aplikasi di http://localhost:8000. Aplikasi stockt hadir dengan dua pengguna default: pengguna administrator (Administrator, [email protected]) dan pengguna biasa (John Doe, [email protected]). (Kedua kata sandi: rahasia) Masuk ke aplikasi sebagai John Doe dan administrator dan buat perubahan pada beberapa produk yang ditampilkan di halaman beranda. Kemudian, sebagai administrator, buka http://localhost:8000/ audits untuk melihat daftar semua perubahan yang dilakukan oleh semua pengguna.

Lihat audit baru secara real time

Sekarang setelah dasbor audit berfungsi, Anda perlu memuat ulang halaman kapan pun Anda ingin melihat perubahan baru. Di sinilah fitur real-time menggunakan Pusher ikut bermain. Mari kita terapkan.

Pertama, atur pusher di bagian backend. Instal paket pusher Laravel:
composer require pusher/pusher-http-laravel
php artisan vendor:publish --provider="Pusher\Laravel\PusherServiceProvider"
Edit config/pusher.php sehingga menjadi seperti ini:
'connections' => [
      'main' => [
        'auth_key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
          'cluster' => env('PUSHER_APP_CLUSTER'),
        ],
        'host' => null,
        'port' => null,
        'timeout' => null,
      ],
    ],

Masuk ke dasboard pusher untuk membuat aplikasi baru. Salin kredensial aplikasi dari bagian Kunci Aplikasi dan tambahkan ke file .env Anda.

PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=your-app-cluster

Catatan: Laravel mungkin men-cache konfigurasi lama, jadi Anda mungkin perlu menjalankan perintah php artisan config:cache untuk melihat nilai konfigurasi baru di proyek Anda.

Paket laravel-auditing memunculkan event yang disebut Audited setiap kali audit baru dibuat. untuk melisten event dan trigger new-audit event pada Pusher. Pada frontend akan melisten event ini dan menambahkan item audit baru ke tabel.

Buat event Listener, app/Listeners/AuditedListener.php dengan konten berikut:
<?php
    
    namespace App\Listeners;
    
    use OwenIt\Auditing\Events\Audited;
    use Pusher\Laravel\Facades\Pusher;
    
    class AuditedListener
    {
      public function handle(Audited $event)
      {
        $audit = $event->audit->toArray();
        $audit['user_name'] = $event->audit->user->name;
        Pusher::trigger('audits', 'new-audit', ['audit' => $audit]);
      }
    }
kemudian, daftarkan event listener pada app/Providers/EventServiceProvider.php:
class EventServiceProvider extends ServiceProvider
    {
      protected $listen = [
          \OwenIt\Auditing\Events\Audited::class => [
              \App\Listeners\AuditedListener::class
              ]
      ];
    
      // ...
    }

Disini code yang di gunakan untuk menghandel event. kami menarik pusher-js libarry, untuk subscribe audit channel dan kemudian bind ke event new-audit. ketika sebuah event ada. kami membangun baris baru dan di insert di bagian atas tabel. tambahkan code ke view anda resources/views/audits.blade.php:

<script src="https://js.pusher.com/4.2/pusher.min.js"></script>
    <script>
      var socket = new Pusher("your-app-key", {
          cluster: 'your-app-cluster',
      });
      socket.subscribe('audits')
          .bind('new-audit', function (data) {
              var audit = data.audit;
              var $modelCell = $('<td>').text(audit.auditable_type + '(id: ' + audit.auditable_id + ')');
              var $eventCell = $('<td>').text(audit.event);
              var $userCell = $('<td>').text(audit.user_name);
              var $timeCell = $('<td>').text(audit.created_at);
    
              function createSubTable(values) {
                var $table = $('<table>').addClass('table');
                  for (attribute in values) {
                    $table.append(
                      $('<tr>').append(
                        $('<td>').text(attribute),
                        $('<td>').text(values[attribute])
                      )
                    );
                  }
                  return $table;
              }
    
              var $oldValuesTable = createSubTable(audit.old_values)
              var $newValuesTable = createSubTable(audit.new_values)
    
              var $oldValuesCell = $('<td>').append($oldValuesTable);
              var $newValuesCell = $('<td>').append($newValuesTable);
    
              $newRow = $('<tr>').append(
                $modelCell,
                $eventCell,
                $userCell,
                $timeCell,
                $oldValuesCell,
                $newValuesCell
              );
              $('#audits').prepend($newRow);
          });
    </script>

Ganti key aplikasi Anda dan kluster aplikasi Anda dengan kunci dan kluster aplikasi Pusher Anda, dan selesai!

Mari kita uji aplikasinya. Luncurkan aplikasi seperti yang dijelaskan di atas. Masuk sebagai John Doe di satu browser dan sebagai Administrator di browser lain sehingga Anda dapat mempertahankan sesi bersamaan. Coba buat perubahan pada beberapa produk sebagai John Doe sambil melihat dasbor sebagai administrator. Perubahan ditampilkan secara real time di dashboard.

Kesimpulan

Pada artikel ini, saya menambahkan dasbor audit ke aplikasi yang sudah ada. Kami telah menambahkan kemampuan waktu nyata dengan menampilkan audit saat terjadi di dasbor. Berkat Laravel dan Pusher, kami dapat mencapai ini dengan sedikit stres. Anda dapat memeriksa kode sumber aplikasi yang sudah selesai di GitHub.