Sunday, July 5, 2026

CARA MEMBUAT CAPTCHA DI LARAVEL 11 KEATAS

 


Untuk di file .env connection standar bawakan yakni mysql captcha akan tampil seperti biasa

namun terkadang jika menggunakan connection sqlsrv, captcha tidak mau tampil jadi ubah dulu

SESSION_DRIVER=database  menjadi  SESSION_DRIVER=file
CACHE_STORE=database  menjadi  CACHE_STORE=file

baru captcha nya akan tampil.

Step 1 – Install the Laravel CAPTCHA package

Jalankan perintah ini untuk install package nya

composer require mews/captcha

Step 2 – Configure CAPTCHA settings

Publish the CAPTCHA configuration file dengan perintah dibawah

php artisan vendor:publish --provider="Mews\Captcha\CaptchaServiceProvider"

Perintah diatas akan membuat file captcha.php didalam config folder.

*perhatikan letak kita menaruh folder background dan fonts captcha dan sesuaikan di file ini, seperti dibawah ini 
folder background dan fonts bisa didownload klik disini
<?php

return [
    'disable' => env('CAPTCHA_DISABLE', false),

    'characters' => [
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    ],

    'fontsDirectory' => dirname(__DIR__) . '/public/assets/captcha/fonts',
    'bgsDirectory' => dirname(__DIR__) . '/public/assets/captcha/assets/backgrounds',

    'default' => [
        'length' => 6,
        'width' => 345,
        'height' => 65,
        'quality' => 90,
        'math' => false,
        'expire' => 60,
        'encrypt' => false,
    ],

    'flat' => [
        'length' => 6,
        'fontColors' => ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f', '#f57c00', '#795548'],
        'width' => 345,
        'height' => 65,
        'math' => false,
        'quality' => 100,
        'lines' => 6,
        'bgImage' => true,
        'bgColor' => '#28faef',
        'contrast' => 0,
    ],

    'mini' => [
        'length' => 3,
        'width' => 60,
        'height' => 32,
    ],

    'inverse' => [
        'length' => 5,
        'width' => 120,
        'height' => 36,
        'quality' => 90,
        'sensitive' => true,
        'angle' => 12,
        'sharpen' => 10,
        'blur' => 2,
        'invert' => false,
        'contrast' => -5,
    ],

    'math' => [
        'length' => 9,
        'width' => 120,
        'height' => 36,
        'quality' => 90,
        'math' => true,
    ],
];

You can use the default settings without any changes.

If needed, you can customize values like:

  • length of CAPTCHA
  • image width and height
  • background and font colors

For example, to change the character length:

'length' => 5,

Most projects can use the default configuration without any changes.

Using different CAPTCHA styles

You can use different CAPTCHA styles defined in the configuration file, such as mini, inverse and more.

To use a specific style, pass its name to the captcha_img() function:

captcha_img('mini')
captcha_img('inverse')

Make sure to update the style in all places where captcha_img() is used.

In this example, it is used in:

  • the form display
  • the reload CAPTCHA method

Both should use the same style to avoid mismatch.

CAPTCHA style comparison

StyleLengthSize (approx)Special featureUse case
default6LargeStandard imageGeneral forms
flat6LargeColored text and backgroundModern UI forms
mini3SmallCompact sizeSmall layouts
inverse5MediumDistortion and contrastBetter readability
math9MediumMath-based CAPTCHAStronger bot protection

Step 3 – Create routes

use App\Http\Controllers\CaptchaController;
Route::get('/', [CaptchaController::class, 'showForm'])->name('captcha.form');
Route::post('/submit', [CaptchaController::class, 'submit'])->name('captcha.submit');
Route::get('/reload-captcha', [CaptchaController::class, 'reloadCaptcha'])->name('captcha.reload');

These routes display the form, handle form submission, and reload the CAPTCHA image.

Step 4 – Create the controller

Create a controller to display the form, validate input, and generate the CAPTCHA image.

php artisan make:controller CaptchaController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class CaptchaController extends Controller
{
    public function showForm()
    {
        return view('captcha-form', [
            'captchaImage' => captcha_img(),
        ]);
    }

    public function submit(Request $request)
    {
        $request->validate([
            'name' => ['nullable', 'string', 'max:100'],
            'email' => ['nullable', 'email'],
            'captcha' => ['required', 'captcha'],
        ], [
            'captcha.required' => 'Enter the CAPTCHA',
            'captcha.captcha' => 'CAPTCHA is incorrect',
        ]);

        return redirect()
            ->route('captcha.form')
            ->with('success', 'Form submitted successfully');
    }

    public function reloadCaptcha()
    {
        return response()->json([
            'captcha' => captcha_img(),
        ]);
    }
}

The controller displays the form, validates the CAPTCHA input, and handles the reload request.

The CAPTCHA image is generated by the mews/captcha package and displayed in the form.

On form submit, the entered value is validated using Laravel’s captcha validation rule. If it does not match, a validation error is shown.

The reload action returns a new CAPTCHA image without refreshing the page.

You can also switch CAPTCHA styles using the configuration file.

You can also switch CAPTCHA styles using the configuration file by passing the style name to the captcha_img() function.

Step 5 – Build the Blade form

Create a Blade view to display the form, CAPTCHA image, and validation messages.

resources/views/captcha-form.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel CAPTCHA Form</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
            background: #f4f6fb;
            color: #1f2937;
        }

        .page {
            max-width: 520px;
            margin: 60px auto;
            padding: 24px;
        }

        .card {
            background: #ffffff;
            border: 1px solid #dbe3f0;
            border-radius: 12px;
            padding: 24px;
            box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
        }

        h1 {
            margin: 0 0 8px;
            font-size: 28px;
        }

        p {
            margin: 0 0 20px;
            color: #4b5563;
        }

        label {
            display: block;
            margin-bottom: 6px;
            font-weight: 700;
        }

        input {
            width: 100%;
            box-sizing: border-box;
            padding: 12px;
            border: 1px solid #cbd5e1;
            border-radius: 8px;
            margin-bottom: 16px;
            font-size: 15px;
        }

        .captcha-row {
            display: flex;
            align-items: center;
            gap: 12px;
            margin-bottom: 16px;
        }

        .captcha-image {
            min-height: 46px;
            padding: 6px;
            border: 1px solid #cbd5e1;
            border-radius: 8px;
            background: #fff;
        }

        button {
            border: 0;
            border-radius: 8px;
            padding: 12px 16px;
            font-size: 15px;
            cursor: pointer;
        }

        .reload-button {
            background: #e2e8f0;
            color: #1e293b;
        }

        .submit-button {
            width: 100%;
            background: #2563eb;
            color: #fff;
            font-weight: 700;
        }

        .message {
            padding: 12px 14px;
            border-radius: 8px;
            margin-bottom: 16px;
        }

        .message.success {
            background: #dcfce7;
            color: #166534;
        }

        .message.error {
            background: #fee2e2;
            color: #b91c1c;
        }

        .field-error {
            margin-top: -10px;
            margin-bottom: 16px;
            color: #b91c1c;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="card">
            <h1>Simple CAPTCHA Form</h1>
            <p>Enter the CAPTCHA code shown in the image before submitting the form.</p>

            @if (session('success'))
                <div class="message success">{{ session('success') }}</div>
            @endif

            @if ($errors->has('captcha'))
                <div class="message error">{{ $errors->first('captcha') }}</div>
            @endif

            <form method="POST" action="{{ route('captcha.submit') }}">
                @csrf

                <label for="name">Name</label>
                <input
                    id="name"
                    type="text"
                    name="name"
                    value="{{ old('name') }}"
                    placeholder="Optional"
                >

                <label for="email">Email</label>
                <input
                    id="email"
                    type="text"
                    name="email"
                    value="{{ old('email') }}"
                    placeholder="Optional"
                >
                @error('email')
                    <div class="field-error">{{ $message }}</div>
                @enderror

                <label for="captcha">CAPTCHA</label>
                <div class="captcha-row">
                    <div class="captcha-image" id="captcha-image">{!! $captchaImage !!}</div>
                    <button class="reload-button" type="button" id="reload-captcha">Reload</button>
                </div>

                <input
                    id="captcha"
                    type="text"
                    name="captcha"
                    placeholder="Enter the CAPTCHA"
                    autocomplete="off"
                >

                <button class="submit-button" type="submit">Submit</button>
            </form>
        </div>
    </div>

    <script>
        document.getElementById('reload-captcha').addEventListener('click', async function () {
            const response = await fetch('{{ route('captcha.reload') }}', {
                headers: {
                    'X-Requested-With': 'XMLHttpRequest'
                }
            });

            const data = await response.json();
            document.getElementById('captcha-image').innerHTML = data.captcha;
            document.getElementById('captcha').value = '';
        });
    </script>
</body>
</html>

The form displays the CAPTCHA image and includes a reload option.

When the reload link is clicked, a new CAPTCHA image is loaded using a simple fetch request.

Sunday, May 31, 2026

Cara Membuat Multiple Koneksi 2 atau lebih database di Laravel (Multi Database Connection)

 1. setting di .env

#koneksi 1

DB_CONNECTION=sqlsrv

DB_HOST=IP Hostnya 1

DB_PORT=1433

DB_DATABASE=nama_database

DB_USERNAME=user_database

DB_PASSWORD=pass_database


#koneksi 2

DB2_CONNECTION=sqlsrv

DB2_HOST=IP Hostnya 2

DB2_PORT=1433

DB2_DATABASE=nama_database2

DB2_USERNAME=user_database2

DB2_PASSWORD=pass_database2


2. setting file config/database.php

*contoh setting SQL SERVER

'sqlsrv' => [

            'driver' => 'sqlsrv',

            'url' => env('DB_URL'),

            'host' => env('DB_HOST', 'localhost'),

            // 'port' => env('DB_PORT', '1433'),

            'database' => env('DB_DATABASE', 'laravel'),

            'username' => env('DB_USERNAME', 'root'),

            'password' => env('DB_PASSWORD', ''),

            'charset' => env('DB_CHARSET', 'utf8'),

            'prefix' => '',

            'prefix_indexes' => true,

            // 'encrypt' => env('DB_ENCRYPT', 'yes'),

            // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),

        ],


        'sqlsrv2' => [

            'driver' => 'sqlsrv',

            'url' => env('DB2_URL'),

            'host' => env('DB2_HOST', 'localhost'),

            // 'port' => env('DB2_PORT', '1433'),

            'database' => env('DB2_DATABASE', 'laravel'),

            'username' => env('DB2_USERNAME', 'root'),

            'password' => env('DB2_PASSWORD', ''),

            'charset' => env('DB2_CHARSET', 'utf8'),

            'prefix' => '',

            'prefix_indexes' => true,

            // 'encrypt' => env('DB2_ENCRYPT', 'yes'),

            // 'trust_server_certificate' => env('DB2_TRUST_SERVER_CERTIFICATE', 'false'),

        ],


* contoh setting MySQL

 'mysql' => [

        'driver' => 'mysql',

        'host' => env('DB_HOST'),

        'port' => env('DB_PORT'),

        'database' => env('DB_DATABASE'),

        'username' => env('DB_USERNAME'),

        'password' => env('DB_PASSWORD'),

        'charset' => 'utf8mb4',

        'collation' => 'utf8mb4_unicode_ci',

    ],


    'mysql2' => [ // koneksi kedua

        'driver' => 'mysql',

        'host' => env('DB2_HOST'),

        'port' => env('DB2_PORT'),

        'database' => env('DB2_DATABASE'),

        'username' => env('DB2_USERNAME'),

        'password' => env('DB2_PASSWORD'),

        'charset' => 'utf8mb4',

        'collation' => 'utf8mb4_unicode_ci',

    ],


3. cara menggunakannya di MODEL

*user.php

class User extends Model

{

     // properti koneksi database

       protected $connection = 'mysql';

}


*produk.php

class Produk extends Model

{

      // properti koneksi database

        protected $connection = 'mysql2';

  

     // properti nama table

        protected $table = 'products';

}


4. cara menggunakannya

*select

$data = DB::connection('mysql2')->table('customers')->get();


*insert

DB::connection('mysql2')->table('logs')->insert([

    'message' => 'Tes koneksi database 2',

]);


*Raw Query

DB::connection('mysql2')->statement('DELETE FROM temp_data');

Friday, September 26, 2025

Cara Enable dan Disable Multiple RDP Remote Desktop Sessions windows

 Dengan multiple RDP sessions, beberapa pengguna dapat terhubung ke komputer yang sama secara bersamaan melalui RDP dan bekerja pada sesi mereka sendiri tanpa mengganggu pengguna lain yang terhubung.

Berikut Langkahnya :

  1. Masuk ke “Local Group Policy Editor”. Caranya dengan klik icon Search dan ketik gpedit.msc, kemudian enter.
  2. Masuk ke “Computer Configuration” > “Administrative Templates” > “Windows Components” > “Remote Desktop Services” > “Remote Desktop Session Host” > “Connections”

3. Di dalam Connections, Ubah “Restrict Remote Desktop Services user to a single Remote Desktop Services session” menjadi Disable

4. Dan ubah “Limit number of connections” menjadi Enable dengan limit 999999 untuk unlimited, atau sesuaikan keinginan berapa limit nya




5. Tutup kembali window “Local Group Policy Editor” dan restart, Anda sudah bisa melakukan remote desktop dari beberapa device secara bersamaan

Monday, March 10, 2025

ERROR "Saving changes is not permitted" pada SQL SERVER

ketika kita akan melakukan perubahan design tabel pada SQL SERVER melalui Microsoft SQL Server Management Studio (SMSS) jika SMSS menampilkan error "Saving changes is not permitted" seperti gambar dibawah ini


Maka lakukan hal berikut :

Masuk menu Tools => Options => Designers => Table and Database Designers
kemudian hilangkan checklist pada bagian "Prevent saving changes that require table re-creation