• Час читання ~11 хв
  • 25.04.2023

Захист вашої програми Laravel за допомогою сертифіката SSL має вирішальне значення для забезпечення завжди зашифрованого трафіку від і до вашої програми. Деякі сертифікати SSL безкоштовні, тоді як інші потрібно придбати та надавати центри сертифікації, такі як letsencrypt та Cloudflare, серед інших.

Створення цих сертифікатів вручну може стати виснажливим завданням, особливо якщо ви поняття не маєте, з чого почати.

Certbot приходить на допомогу, надаючи безкоштовний та автоматизований спосіб створення та оновлення цих сертифікатів.

Для цього потрібно вручну генерувати сертифікати через Certbot. Ви можете прочитати більше про те, як додати сертифікати SSL після розгортання робочої версії програми.

Іноді нам може знадобитися створити ці сертифікати в масштабі, особливо в додатку з кількома орендарями. Хорошим прикладом є Slack. Slack надає кожній команді унікальний піддомен, такий як team.slack.com.

Використовуючи ту саму аналогію, ми також можемо надавати користувачам безкоштовні субдомени, як тільки вони підключаються до нашого додатка з кількома клієнтами або як тільки вони надають власні користувацькі домени. Нам також доведеться генерувати сертифікати SSL для цих доменних імен.

Нам потрібно знайти спосіб, як ми можемо генерувати сертифікати SSL у масштабі. Існує кілька способів вирішення цієї проблеми, таких як використання сервера Caddy. Сервер Caddy надає безкоштовні сертифікати SSL для кожного хоста, що робить його легкою технологією для додавання до нашого стека.

Іншим варіантом є використання Certbot та створення цих сертифікатів, якщо ми використовуємо Apache або Nginx. У цьому підручнику я продемонструю, як автоматизувати це завдання для підходу на основі Nginx.

Це продовження цієї статті, де ми створили просту службу скорочення URL-адрес і додали функцію, що дозволяє користувачам додавати свої власні домени.

Ми створимо сертифікати SSL, як тільки користувачі додадуть свої власні доменні імена до системи та оновлять свої записи DNS, щоб вказати на наш скорочувач

URL-адрес. Рефакторинг коду

У попередній частині цієї серії ми зберігали доменні імена в таблиці користувача. Хоча це добре для простого скорочувача URL-адрес, у більшості випадків клієнт може мати кілька доменних імен. Тому нам знадобиться спосіб обробки декількох доменів для одного користувача.

Ми створимо новий файл міграції, який скине стовпець домену з таблиці користувачів

php artisan make:migration drop_domain_column_from_users_table --table=users
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('domain');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('domain')->nullable()->after('email');
        });
    }
};

Потім ми створимо нову модель домену, яка буде містити всі доменні імена.

php artisan make:model Domains -m
<?php

namespace App\Models;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Domains extends Model
{
    use HasFactory;

    protected $guarded= [];

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}

Модель доменів

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('domains', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
            $table->string('domain');
            $table->boolean('status')->default(0);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('domains');
    }
};

Файл

міграції доменів Тепер користувач зможе додати кілька доменів до системи.

Давайте тепер розберемося з DNS-стороною речей.

Робота з DNS

Система доменних імен - це служба, яка допомагає перетворити зручні для читання людиною доменні імена, такі як iankumu.com, в IP-адреси

Для нашого скорочувача URL-адрес ми дозволяли користувачам додавати свої власні домени. Це означає, що нам потрібно надати їм деякі записи DNS, які вони додадуть своїм постачальникам DNS, щоб завершити зіставлення з нашою програмою

скорочення Ми можемо використовувати два записи: записи A або Cname. Запис зіставляє ім'я домену з IP-адресою, а запис Cname зіставляє одне ім'я домену з іншим.

Ви можете прочитати цей посібник, щоб зрозуміти їх відмінності та який вибрати. Залежно від ваших потреб ви можете вибрати те чи інше.

Для мого випадку я виберу записи Cname. Я попрошу користувачів додати запис Cname, що вказує на short.app.com

Тому у своїх записах DNS на Namecheap я додам цей запис до користувацького домену, який я хочу використовувати в програмі

Type Host Value TTL
CNAME Record go short.app.com Automatic
Namecheap DNS Records

скорочення URL-адрес. Це зіставить go.example.com домену з short.app.com.

Після цього мій користувацький домен готовий до використання.

Встановлення certbot

У попередній частині цього підручника ми встановили Nginx на наш сервер. Тепер ми хочемо встановити Certbot.

Ми можемо дотримуватися цього підручника, щоб встановити Certbot на Nginx.

Генерація SSL сертифікатів за допомогою laravel і certbot.

Тепер, коли встановлено рівень DNS і встановлено Certbot, тепер ми можемо генерувати сертифікати SSL для користувачів.

Перш ніж створювати будь-які сертифікати SSL, спочатку потрібно переконатися, що записи DNS поширилися правильно. Ми будемо використовувати функцію dns_get_record helper для отримання DNS-записів доменного імені.

//App/Utils/DomainHelper.php

<?php

namespace App\Utils;

class DomainHelper
{
    public $isfound = false;

    public function verifycname($domain)
    {
        $domain = parse_url($domain);

        $host = array_key_exists('host', $domain) ? $domain['host'] : $domain['path'];

        $records = dns_get_record($host, DNS_CNAME);

        if (!empty($records)) {
            foreach ($records as $record) {
                if ($record['target'] == "short.app.com") {
                    $this->isfound = true;
                    break;
                } else {
                    $this->isfound = false;
                }
            }
        } else {
            $this->isfound = false;
        }

        return $this->isfound;
    }
}

Поширення записів DNS може зайняти до 48 годин, і, таким чином, нам потрібно мати спосіб перевірити, чи поширилися записи DNS.

Ви можете запланувати роботу для виконання цих перевірок. У моєму випадку я просто пропущу цю частину. Як тільки записи поширяться, ми додамо домен в чергу для генерації

SSL. Генерація SSL сертифікатів Наступним кроком є створення сертифікатів

SSL. Ми будемо використовувати новий фасад Process для роботи з Certbot. Це дозволить нам запускати зовнішні процеси з нашого додатка Laravel.

Ми створимо нову конфігурацію у файлі config/services.php , яка дозволить нам змінювати середовище Certbot відповідно до наших потреб.

//config/services.php
<?php

...

'certbot' => [
        'test' => env('CERTBOT_TEST', true)
    ]

...

Ця конфігурація допоможе нам визначити, яку команду Certbot виконувати.

//App/Utils/SSLManager.php
<?php

namespace App\Utils;

use App\Models\User;
use App\Models\Domains;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;

class SSLManager
{
    public function generateSSL($domain, $email = null)
    {
        $command = $this->certbot_command($domain, $email);

        $certbot = Process::path(base_path())->start($command);

        $process = $certbot->wait();

        if ($process->successful()) {
            return $process->output();
        }


    }

    public function certbot_command($domain, $email): string
    {

        if (config('services.certbot.test') == true) {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email --test-cert";
        } else {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email";
        }

        return $command;
    }

Ми використовуємо прапорець certonly, щоб доручити certbot лише генерувати сертифікат SSL, але не оновлювати конфігураційний файл Nginx. Це тому, що ми хочемо підготувати власний конфігураційний файл Nginx для всіх доменів у нашій системі.

Ми також використовуємо прапорець -test-cert для використання проміжного середовища , наданого let's encrypt. Це допоможе збільшити ліміт сертифікатів на домен до 30 000 на тиждень і надасть нам тестові сертифікати SSL, які ми можемо використовувати для перевірки нашої логіки.

У виробничому середовищі один домен може запитувати лише 5 сертифікатів на тиждень.

Тепер давайте підготуємо простий конфігураційний файл, який буде проксі-запити до нашого скорочувача URL-адрес.

//App/Utils/SSLManager.php
<?php

...

public function nginx_config($domain): string
    {
        $host = "short.app.com";

        $content = "
        server {
            if (\$host = $domain) {
               return 301 https://\$host\$request_uri;
            }
            listen 80;
            listen [::]:80;
            server_name $domain;
        }
        server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name $domain;
            return 301 https://$host\$request_uri;
            resolver 8.8.8.8;
            location / {
                include proxy_params;
                proxy_pass https://$host\$request_uri;
                proxy_set_header Host $domain;
                proxy_set_header X-Forwarded-Host \$http_host;
                proxy_set_header X-Real-IP \$remote_addr;
                proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto \$scheme;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade \$http_upgrade;
            }
            ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/$domain/chain.pem;
            include /etc/letsencrypt/options-ssl-nginx.conf;
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        }";

        return $content;
    }

...

Наш додаток попередньо заповнить змінні $host та $domain правильними параметрами для кожного доменного імені

Ми створимо ці конфігураційні файли в папці, доступній для сайтів, для Nginx.

Конфігурації будуть створюватися динамічно за допомогою нашого додатка.

//App/Utils/SSLManager
<?php

namespace App\Utils;

use App\Models\User;
use App\Models\Domains;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;

class SSLManager
{
    public function generateSSL($domain, $email = null): bool
    {
        $command = $this->certbot_command($domain, $email);

        $certbot = Process::path(base_path())->start($command);

        $process = $certbot->wait();


        if ($process->successful()) {
            $file_path = "/etc/nginx/sites-available/$domain";

            if (File::exists($file_path)) {
                $nginx = File::put($file_path, $this->nginx_config($domain));
            } else {
                touch($file_path);
                $nginx = File::put($file_path, $this->nginx_config($domain));
            }

            if ($nginx) {
                $symlink = $this->execute($this->symlink($domain));
                if ($symlink->successful()) {
                    $finally = $this->execute('sudo nginx -t && sudo systemctl reload nginx');
                    if ($finally->successful()) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        } else {
            return false;
        }
    }

    public function certbot_command($domain, $email): string
    {

        if (config('services.certbot.test') == true) {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email --test-cert";
        } else {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email";
        }

        return $command;
    }

    public function nginx_config($domain): string
    {
        $host = "short.app.com";

        $content = "
        server {
            if (\$host = $domain) {
               return 301 https://\$host\$request_uri;
            }
            listen 80;
            listen [::]:80;
            server_name $domain;
        }
        server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name $domain;
            return 301 https://$host\$request_uri;
            resolver 8.8.8.8;
            location / {
                include proxy_params;
                proxy_pass https://$host\$request_uri;
                proxy_set_header Host $domain;
                proxy_set_header X-Forwarded-Host \$http_host;
                proxy_set_header X-Real-IP \$remote_addr;
                proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto \$scheme;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade \$http_upgrade;
            }
            ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/$domain/chain.pem;
            include /etc/letsencrypt/options-ssl-nginx.conf;
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        }";

        return $content;
    }

    private function symlink($domain): string
    {
        return "sudo ln -s /etc/nginx/sites-available/$domain /etc/nginx/sites-enabled/";
    }

    private function execute($command)
    {
        return Process::path(base_path())->run($command);
    }

Тепер ми створимо роботу , яка буде обробляти генерацію сертифікатів SSL.

php artisan make:job GenerateSSLJob
//App/Jobs/GenerateSSLJob
<?php

namespace App\Jobs;

use App\Utils\SSLManager;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Throwable;

class GenerateSSLJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $domain;

    public $email;

    public function __construct($domain, $email = null)
    {
        $this->domain = $domain;
        $this->email = $email;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        (new SSLManager())->generateSSL($this->domain, $this->email);
    }
}

На цьому наш генератор SSL сертифікатів готовий.

Тепер ми можемо використовувати користувацький домен у нашому скорочувачі

URL-адрес. Видалення сертифікатів SSL

Оскільки ми створюємо сертифікати SSL у великих масштабах, нам потрібен спосіб їх видалення, як тільки користувач покинув нашу платформу.

Ми можемо створити інший метод, який впорається з цим завданням за нас.

//App/Utils/SSLManager.php
<?php


...
  public function deleteSSL(User $user)
    {
        $domains = $this->getUserDomains($user);

        if (!empty($domains)) {
            foreach ($domains as $domain) {
                $nginx_path = "/etc/nginx/sites-available/$domain";
                $this->deleteConfig($nginx_path);
                $this->execute("sudo rm -rf /etc/nginx/sites-enabled/$domain");
                $this->execute("sudo certbot delete --cert-name $domain --non-interactive");
            }

            $finally = $this->execute('sudo nginx -t && sudo systemctl reload nginx');
            if ($finally->successful()) {

                return true;
            } else {
                return false;
            }
        }
    }

    public function getUserDomains(User $user)
    {
        return Domains::where('user_id', $user->id)->pluck('domain')->toArray();
    }

    public function deleteConfig($file_path)
    {
        if (File::exists($file_path)) {
            return File::delete($file_path);
        } else {
            return false;
        }
    }

...

На цьому кроці також можна відкликати сертифікати , щоб також додати сюди логіку.

Уточнення нашого коду

Ми можемо додати деякі допоміжні функції, які допоможуть зробити наш додаток ще кращим.

Перевірка доменних імен

Оскільки ми дозволяємо користувачам додавати власні домени, у нас можуть бути випадки, коли користувачі "випадково" додають недійсні доменні імена. Тому нам потрібен спосіб гарантувати, що лише дійсні доменні імена матимуть право на генерацію SSL.

Давайте додамо ще один метод, який підтвердить доменне ім'я

//App/Utils/DomainHelper.php
<?php

...

public function is_valid_domain_name($domain_name)
    {
        return preg_match("/^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,6}$/", $domain_name);
    }
...

Ми використовуємо простий регекс, який я "запозичив" у чату gpt🙂, щоб перевірити домен і повернути, дійсний він чи ні.

Автоматизуйте поновлення

SSL Термін дії сертифікатів SSL Letsencrypt закінчується через 90 днів. На щастя, Certbort може оновити сертифікати SSL для нас.

Давайте додамо метод, який оновить доменні імена для нас

//App/Utils/SSLManager.php
<?php

...

 public function renewSSL($domain)
    {
        $command = "sudo certbot certonly --force-renew -d $domain";
        return $this->execute($command);
    }

...

Нам знадобиться спосіб дізнатися, коли поновлювати ці сертифікати SSL. Давайте додамо новий стовпець у таблицю доменів, який міститиме дату поновлення.

php artisan make:migration add_renewal_column_to_domains_table --table=domains
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('domains', function (Blueprint $table) {
            $table->dateTime('renewal_date')->nullable()->after('status');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('domains', function (Blueprint $table) {
            $table->dropColumn('renewal_date');
        });
    }
};

Потім ми підготуємо нашу роботу для поновлення цих доменів

php artisan make:job RenewSSLJob
<?php

namespace App\Jobs;

use App\Utils\SSLManager;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class RenewSSLJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     */
    public $domains;
    public function __construct(array $domains)
    {
        $this->domains = $domains;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        foreach ($this->domains as $domain) {
            (new SSLManager())->renewSSL($domain);
        }
    }
}

Нарешті, ми заплануємо команду на щоденний запуск. Ми отримаємо всі домени, термін дії яких закінчується через місяць, і продовжимо їх.

Ми хочемо поновити їх за 30 днів до закінчення терміну їх дії, щоб запобігти закінченню терміну дії сертифікатів SSL на нашому сервері.

//App/Console/Kernel.php

<?php

namespace App\Console;

use App\Jobs\RenewSSLJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
        // $schedule->command('inspire')->hourly();

        $renewalDate = Carbon::now()->addDays(30)->toDateTimeString();

        $domains = DB::table('domains')
            ->where('renewal_date', '<=', $renewalDate)
            ->pluck('domain')
            ->toArray();

        if (!empty($domains)) {
             $schedule->job(new RenewSSLJob($domains))->daily();
        }
    }

    /**
     * Register the commands for the application.
     */
    protected function commands(): void
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }
}

Останній клас помічників повинен нагадувати наведений нижче

//App/Utils/SSLManager.php
<?php

namespace App\Utils;

use App\Models\User;
use App\Models\Domains;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;

class SSLManager
{
    public function generateSSL($domain, $email = null): bool
    {
        $command = $this->certbot_command($domain, $email);

        $certbot = Process::path(base_path())->start($command);

        $process = $certbot->wait();


        if ($process->successful()) {
            $file_path = "/etc/nginx/sites-available/$domain";

            if (File::exists($file_path)) {
                $nginx = File::put($file_path, $this->nginx_config($domain));
            } else {
                touch($file_path);
                $nginx = File::put($file_path, $this->nginx_config($domain));
            }

            if ($nginx) {
                $symlink = $this->execute($this->symlink($domain));
                if ($symlink->successful()) {
                    $finally = $this->execute('sudo nginx -t && sudo systemctl reload nginx');
                    if ($finally->successful()) {
                        DB::table('domains')->where('domain', '=', $domain)->update([
                            'status' => 1,
                            'renewal_date' => now()->toDateTimeString()
                        ]);

                        return true;
                    } else {
                        return false;
                    }
                }
            }
        } else {
            return false;
        }
    }

    public function certbot_command($domain, $email): string
    {

        if (config('services.certbot.test') == true) {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email --test-cert";
        } else {
            $command = "sudo certbot certonly --nginx --agree-tos --no-eff-email -d $domain --email $email";
        }

        return $command;
    }

    public function nginx_config($domain): string
    {
        $host = "short.app.com";

        $content = "
        server {
            if (\$host = $domain) {
               return 301 https://\$host\$request_uri;
            }
            listen 80;
            listen [::]:80;
            server_name $domain;
        }
        server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name $domain;
            return 301 https://$host\$request_uri;
            resolver 8.8.8.8;
            location / {
                include proxy_params;
                proxy_pass https://$host\$request_uri;
                proxy_set_header Host $domain;
                proxy_set_header X-Forwarded-Host \$http_host;
                proxy_set_header X-Real-IP \$remote_addr;
                proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto \$scheme;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade \$http_upgrade;
            }
            ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
            ssl_trusted_certificate /etc/letsencrypt/live/$domain/chain.pem;
            include /etc/letsencrypt/options-ssl-nginx.conf;
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        }";

        return $content;
    }

    private function symlink($domain): string
    {
        return "sudo ln -s /etc/nginx/sites-available/$domain /etc/nginx/sites-enabled/";
    }

    private function execute($command)
    {
        return Process::path(base_path())->run($command);
    }

    public function renewSSL($domain)
    {
        $command = "sudo certbot certonly --force-renew -d $domain";
        return $this->execute($command);
    }

    public function deleteSSL(User $user)
    {
        $domains = $this->getUserDomains($user);

        if (!empty($domains)) {
            foreach ($domains as $domain) {
                $nginx_path = "/etc/nginx/sites-available/$domain";
                $this->deleteConfig($nginx_path);
                $this->execute("sudo rm -rf /etc/nginx/sites-enabled/$domain");
                $this->execute("sudo certbot delete --cert-name $domain --non-interactive");
            }

            $finally = $this->execute('sudo nginx -t && sudo systemctl reload nginx');
            if ($finally->successful()) {
                return true;
            } else {
                return false;
            }
        }
    }

    public function getUserDomains(User $user)
    {
        return Domains::where('user_id', $user->id)->pluck('domain')->toArray();
    }

    public function deleteConfig($file_path)
    {
        if (File::exists($file_path)) {
            return File::delete($file_path);
        } else {
            return false;
        }
    }
}

Остаточний клас

SSLManager Зв'язування всього

цього Давайте зберемо все воєдино через контролер

php artisan make:controller DomainController
<?php

namespace App\Http\Controllers;

use App\Jobs\GenerateSSLJob;
use App\Models\Domains;
use App\Utils\DomainHelper;
use Illuminate\Http\Request;

class DomainController extends Controller
{

    public function store(Request $request)
    {
        $domain_name = $request->input('domain');
        $email = auth()->user()->email;

        if ((new DomainHelper())->is_valid_domain_name($domain_name)) {
            $domain = Domains::create([
                'user_id' => auth()->id(),
                'domain' => $domain_name,
                'status' => 0
            ]);

            if ((new DomainHelper())->verifycname($domain_name)) {
                $job = (new GenerateSSLJob($domain_name, $email));
                dispatch($job);
            }

            return $domain;
        } else {
            return response()->json([
                'message' => $domain_name . 'is not a valid domain name. Ensure your domain name is valid',
            ], 406);
        }
    }
}

висновок І

все. Ми автоматизували процес генерації та продовження SSL сертифікатів за допомогою laravel.

Сподіваюся, ця стаття була проникливою і показала вам, як автоматизувати генерацію та оновлення SSL за допомогою laravel.

Ви можете налаштувати логіку відповідно до ваших потреб. Для мене я використовував простий приклад скорочувача URL-адрес , і саме так я досяг автоматизації генерації SSL.

Якщо у вас виникли запитання, не соромтеся задавати їх у розділі коментарів.

Дякую, що прочитали.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297