Add Laravel Sanctum for API authentication and update routes

- Included `laravel/sanctum` in `composer.json` for lightweight API authentication.
- Updated `User` model to use `HasApiTokens` trait for token management.
- Configured API routing in `bootstrap/app.php`.
- Modified `DatabaseSeeder` to include `ShieldSeeder` and adjusted `FillJsonData` seeder method.
- Changed JSON data path in `ProvincesMigrator` for testing purposes.
- Updated web routes to utilize `MigrationController` for better organization.
This commit is contained in:
Mekan1206
2025-12-21 19:50:38 +05:00
parent 76c05ebe7c
commit 1870583441
14 changed files with 307 additions and 12 deletions

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Database\Seeders\Migrators\ActionEventsMigrator;
use Database\Seeders\Migrators\BranchUserMigrator;
use Database\Seeders\Migrators\CurrencyRatesMigrator;
use Database\Seeders\Migrators\LoanOrderRequiredDocsMigrator;
use Database\Seeders\Migrators\LoanOrdersMigrator;
use Database\Seeders\Migrators\LoanTypesMigrator;
use Database\Seeders\Migrators\MediaMigrator;
use Database\Seeders\Migrators\ProvincesMigrator;
use Database\Seeders\Migrators\BranchesMigrator;
use Database\Seeders\Migrators\UsersMigrator;
use Database\Seeders\Migrators\CardStatesMigrator;
use Database\Seeders\Migrators\CardTypesMigrator;
use Database\Seeders\Migrators\VisaMasterPaymentOrdersMigrator;
use Database\Seeders\Migrators\VerificationsMigrator;
use Database\Seeders\Migrators\PersonalAccessTokensMigrator;
class MigrationController extends Controller
{
public function index()
{
$migrators = [
new ActionEventsMigrator(),
new UsersMigrator(),
new ProvincesMigrator(),
new BranchesMigrator(),
new BranchUserMigrator(),
new CardStatesMigrator(),
new CardTypesMigrator(),
new VerificationsMigrator(),
new CurrencyRatesMigrator(),
new LoanOrderRequiredDocsMigrator(),
new PersonalAccessTokensMigrator(),
new LoanTypesMigrator(),
new LoanOrdersMigrator(),
new MediaMigrator(),
new ProvincesMigrator(),
new VisaMasterPaymentOrdersMigrator(),
];
foreach ($migrators as $migrator) {
$migrator->migrate();
}
return 'done';
}
}

View File

@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Date;
use Laravel\Sanctum\HasApiTokens;
/**
* @property int $id
@@ -28,6 +29,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar
use Notifiable;
use UserAdjustments;
use HasApiTokens;
/**
* The attributes that are mass assignable.

View File

@@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)

View File

@@ -15,6 +15,7 @@
"halaxa/json-machine": "^1.2",
"joaopaulolndev/filament-edit-profile": "^2.0",
"laravel/framework": "^12.0",
"laravel/sanctum": "^4.0",
"laravel/tinker": "^2.10.1",
"laravel/ui": "^4.6",
"mpdf/mpdf": "^8.2",

65
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3fe345d22ddaf5b75cd17aaecee2b718",
"content-hash": "018635a80495002683ac3d2f58dd6eaf",
"packages": [
{
"name": "abdulmajeed-jamaan/filament-translatable-tabs",
@@ -3355,6 +3355,69 @@
},
"time": "2025-11-21T20:52:52+00:00"
},
{
"name": "laravel/sanctum",
"version": "v4.2.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/console": "^11.0|^12.0",
"illuminate/contracts": "^11.0|^12.0",
"illuminate/database": "^11.0|^12.0",
"illuminate/support": "^11.0|^12.0",
"php": "^8.2",
"symfony/console": "^7.0"
},
"require-dev": {
"mockery/mockery": "^1.6",
"orchestra/testbench": "^9.15|^10.8",
"phpstan/phpstan": "^1.10"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Laravel\\Sanctum\\SanctumServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Sanctum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.",
"keywords": [
"auth",
"laravel",
"sanctum"
],
"support": {
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2025-11-21T13:59:03+00:00"
},
{
"name": "laravel/serializable-closure",
"version": "v2.0.7",

84
config/sanctum.php Normal file
View File

@@ -0,0 +1,84 @@
<?php
use Laravel\Sanctum\Sanctum;
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort(),
// Sanctum::currentRequestHost(),
))),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. This will override any values set in the token's
| "expires_at" attribute, but first-party sessions are not affected.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Token Prefix
|--------------------------------------------------------------------------
|
| Sanctum can prefix new tokens in order to take advantage of numerous
| security scanning initiatives maintained by open source platforms
| that notify developers if they commit tokens into repositories.
|
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
*/
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
];

View File

@@ -0,0 +1,33 @@
<?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('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->text('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable()->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
};

View File

@@ -13,9 +13,7 @@ class DatabaseSeeder extends Seeder
public function run(): void
{
$this->call([
FillJsonData::class,
// UsersTableSeeder::class,
// ShieldSeeder::class,
ShieldSeeder::class,
]);
}
}

View File

@@ -9,7 +9,10 @@ class FillJsonData extends Seeder
/**
* Run the database seeds.
*/
public function run(): void {}
public function run(): void
{
}
protected function seedUsers(): void
{

View File

@@ -0,0 +1,26 @@
<?php
namespace Database\Seeders\Migrators;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class PersonalAccessTokensMigrator
{
public function migrate(): void
{
DB::table('personal_access_tokens')->truncate();
$path = database_path('data/tested/personal_access_tokens.json');
$rawData = File::json($path);
foreach ($rawData as $data) {
DB::table('personal_access_tokens')
->insert($data);
}
DB::statement("SELECT setval('personal_access_tokens_id_seq', (SELECT MAX(id) from personal_access_tokens));");
DB::statement("SELECT nextval('personal_access_tokens_id_seq');");
}
}

View File

@@ -11,7 +11,7 @@ class ProvincesMigrator
{
DB::table('provinces')->truncate();
$path = database_path('data/nurmuhammetsdb/provinces.json');
$path = database_path('data/tested/provinces.json');
$rawData = File::json($path);

View File

@@ -0,0 +1,26 @@
<?php
namespace Database\Seeders\Migrators;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class VerificationsMigrator
{
public function migrate(): void
{
DB::table('verifications')->truncate();
$path = database_path('data/tested/verifications.json');
$rawData = File::json($path);
foreach ($rawData as $data) {
DB::table('verifications')
->insert($data);
}
DB::statement("SELECT setval('verifications_id_seq', (SELECT MAX(id) from verifications));");
DB::statement("SELECT nextval('verifications_id_seq');");
}
}

8
routes/api.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');

View File

@@ -1,16 +1,12 @@
<?php
use App\Http\Controllers\MigrationController;
use Database\Seeders\Migrators\MediaMigrator;
use Illuminate\Support\Facades\Route;
Route::redirect('/', filament_path());
Route::get('test', function () {
(new MediaMigrator)->migrate();
return 'done';
});
Route::get('test', [MigrationController::class, 'index']);
// Route::middleware(['auth'])->group(function () {
// Route::get('password-change', [PasswordChangeController::class, 'index'])->name('password-change');
// Route::post('password-change', [PasswordChangeController::class, 'update'])->name('password-change.update');