Laravel Sanctum ve Passport ile API Kimlik Doğrulama

# Laravel Sanctum ve Passport ile API Kimlik Doğrulama Laravel'de API kimlik doğrulama için iki resmi paket bulunur: **Sanctum** ve **Passport**. İki...

Laravel Sanctum ve Passport ile API Kimlik Doğrulama

Laravel Sanctum ve Passport ile API Kimlik Doğrulama

Laravel'de API kimlik doğrulama için iki resmi paket bulunur: Sanctum ve Passport. İkisi de token tabanlı çalışır ama farklı ihtiyaçlara hitap eder. Bu rehberde hangi paketi ne zaman seçeceğinizi, her ikisinin de kurulum ve kullanım adımlarını ve güvenlik açısından dikkat edilmesi gereken noktaları ele alıyoruz.

Önkoşullar ve Kapsam

  • Laravel 10 veya üzeri bir proje (Sanctum ve Passport bu sürümlerde birinci taraf paket olarak gelir).
  • Composer ve php artisan komutlarını çalıştırabiliyor olmak.
  • users tablosu ve standart Laravel kimlik doğrulama iskeleti.
  • API rotalarının routes/api.php üzerinden tanımlandığı varsayılır.

Sürüm numarası vermediğim yerlerde paketlerin güncel kararlı sürümünü kastettiğimi unutmayın; kurulumdan önce Composer'ın çözdüğü sürümü kontrol edin.

Sanctum mu, Passport mu?

İki paketin temel farkı kapsam ve karmaşıklık düzeyidir.

Sanctum, hafif bir kimlik doğrulama paketidir. İki senaryoyu destekler:

  1. SPA (Single Page Application) kimlik doğrulaması: Aynı alan adındaki birinci taraf frontend'ler için çerez tabanlı oturum kimlik doğrulaması.
  2. Basit API token'ları: Mobil uygulama veya üçüncü taraf istemciler için kullanıcıya bağlı, veritabanında saklanan token'lar.

Passport, tam kapsamlı bir OAuth2 sunucusudur. Yetkilendirme kodu, istemci kimlik bilgileri, kişisel erişim token'ları, token yenileme ve kapsam (scope) yönetimi gibi OAuth2 akışlarını destekler.

Pratik seçim kuralı:

  • Yalnızca kendi SPA'nız veya mobil uygulamanız için token üretiyorsanız Sanctum yeterlidir ve daha az bakım gerektirir.
  • Üçüncü taraf uygulamaların sizin API'niz üzerinden kullanıcı adına işlem yapmasını istiyorsanız, OAuth2 akışlarına (yetkilendirme kodu, refresh token) ihtiyacınız varsa Passport gerekir.

Çoğu iç proje için Sanctum doğru başlangıçtır; Passport'u yalnızca gerçekten OAuth2 gerektiğinde ekleyin.

Sanctum ile API Token Kimlik Doğrulama

Kurulum

Sanctum'u Composer ile ekleyin:

composer require laravel/sanctum

Ardından migration dosyalarını yayınlayıp çalıştırın:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

HasApiTokens trait'ini kullanıcı modelinize ekleyin:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;

    // ...
}

Token Üretme

Kullanıcı giriş yaptıktan sonra token üretmek için:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

Route::post('/login', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    $user = \App\Models\User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['Giriş bilgileri hatalı.'],
        ]);
    }

    $token = $user->createToken('api-token')->plainTextToken;

    return response()->json(['token' => $token]);
});

createToken metodu bir token nesnesi döner. plainTextToken özelliği yalnızca bu anda erişilebilir; veritabanında token'ın hash'lenmiş hâli saklanır. Bu değeri istemciye bir kez gönderip kaybettiğinizde yeniden üretmeniz gerekir.

Token Yetenekleri (Abilities)

Token'a yetenek atayarak erişimi sınırlandırabilirsiniz:

$token = $user->createToken('api-token', ['posts:read', 'posts:write'])->plainTextToken;

Rota tarafında bu yetenekleri kontrol edin:

Route::middleware('auth:sanctum')->get('/posts', function (Request $request) {
    if (! $request->user()->tokenCan('posts:read')) {
        abort(403);
    }

    // ...
});

Rotaları Korumak

routes/api.php içinde korumalı rotaları auth:sanctum middleware'i ile işaretleyin:

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn (Request $request) => $request->user());
    Route::post('/logout', function (Request $request) {
        $request->user()->currentAccessToken()->delete();
        return response()->noContent();
    });
});

Beklenen Davranış

  • İstemci, Authorization: Bearer <token> başlığıyla istek gönderir.
  • Geçerli token varsa $request->user() ilgili kullanıcıyı döner.
  • Geçersiz veya silinmiş token'da istek 401 Unauthorized ile reddedilir.
  • currentAccessToken()->delete() yalnızca o isteği yapan token'ı siler; tokens()->delete() ise kullanıcının tüm token'larını iptal eder.

Passport ile OAuth2

Kurulum

composer require laravel/passport
php artisan migrate
php artisan passport:install

passport:install komutu şifreleme anahtarlarını üretir ve iki adet OAuth2 istemcisi (biri kişisel erişim, biri şifre hibesi için) oluşturur. Üretilen client_id ve client_secret değerlerini güvenli biçimde saklayın.

Kullanıcı modeline HasApiTokens trait'ini ekleyin:

use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;
}

config/auth.php içinde api guard'ının sürücüsünü passport yapın:

'guards' => [
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Token Üretme (Şifre Hibesi)

use Illuminate\Support\Facades\Http;

$response = Http::asForm()->post(config('app.url') . '/oauth/token', [
    'grant_type' => 'password',
    'client_id' => config('passport.password_client_id'),
    'client_secret' => config('passport.password_client_secret'),
    'username' => $request->email,
    'password' => $request->password,
    'scope' => '',
]);

return response()->json($response->json());

Bu istek başarılı olduğunda access_token, refresh_token ve expires_in alanlarını içeren bir yanıt döner. client_secret değerini asla istemci tarafına göndermeyin; bu akış sunucu-sunucu veya güvenilir istemci senaryosu içindir.

Rotaları Korumak

Route::middleware('auth:api')->get('/user', fn (Request $request) => $request->user());

Kapsamlar (Scopes)

Passport'ta izinler kapsam üzerinden tanımlanır. AuthServiceProvider içinde kapsamları kaydedin:

use Laravel\Passport\Passport;

public function boot(): void
{
    Passport::tokensCan([
        'posts:read' => 'Gönderileri oku',
        'posts:write' => 'Gönderi oluştur ve güncelle',
    ]);
}

Rota tarafında kapsam kontrolü:

Route::middleware(['auth:api', 'scope:posts:read'])->get('/posts', /* ... */);

Beklenen Davranış

  • İstemci, Authorization: Bearer <access_token> başlığıyla istek gönderir.
  • Token süresi dolduğunda 401 döner; istemci refresh_token ile yeni bir access token alır.
  • Kapsam dışı bir rotaya erişim 403 ile reddedilir.

Yaygın Hatalar

  • Plain text token'ı kaydetmek: Sanctum'da plainTextToken yalnızca üretim anında elde edilir. Veritabanında saklanan değer hash'tir; karşılaştırma için plainTextToken'ı kullanmayın.
  • client_secret'ı istemciye gömmek: Passport'ta istemci sırrı sunucu tarafında kalmalıdır. Mobil veya tarayıcı uygulamasına gömmek sızıntıya yol açar.
  • Sanctum'u Passport ile karıştırmak: İki paketi aynı projede aynı amaçla kullanmak guard çakışmalarına ve kafa karışıklığına neden olur. Birini seçin.
  • Token iptalini unutmak: Çıkış (logout) akışında currentAccessToken()->delete() çağırmazsanız token geçerli kalır.
  • SPA için yanlış yöntem: Aynı alan adındaki SPA'da Bearer token yerine Sanctum'un çerez tabanlı (stateful) akışını kullanmak CSRF koruması açısından daha doğrudur.

Güvenlik Notları

  • HTTPS zorunlu: Bearer token'lar düz HTTP üzerinden gönderilirse ağ üzerinde ele geçirilebilir. Tüm API trafiği TLS üzerinden akmalıdır.
  • Token ömrü: Sanctum token'ları varsayılan olarak süresizdir. config/sanctum.php içindeki expiration ayarıyla ömür tanımlayın. Passport'ta access token ömrü Passport::tokensExpireIn() ile ayarlanır.
  • Kapsam en az yetki ilkesi: Token'lara yalnızca gereken yetenekleri/kapsamları verin. Geniş yetkili token sızarsa etki alanı büyür.
  • Rate limiting: Giriş ve token uç noktalarına throttle middleware'i ekleyin; kaba kuvvet denemelerini sınırlar.
  • Token saklama: İstemci tarafında token'ları localStorage yerine mümkünse güvenli çerez veya platformun güvenli depolama mekanizmasında tutun.

Sonuç

Sanctum, kendi uygulamalarınız için token üretip yönetmenin en sade yoludur; SPA ve mobil senaryoların büyük kısmını karşılar. Passport ise üçüncü taraf entegrasyonları veya standart OAuth2 akışları gerektiğinde devreye girer. Seçimi ihtiyacınıza göre yapın, token ömrü ve kapsamları baştan tanımlayın ve tüm trafiği HTTPS üzerinden taşıyın.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz