# 2026'da Symfony REST API Güvenliği: OAuth2, Rate Limiting ve Mülakat Soruları > Symfony REST API'lerini OAuth2 token introspection, rate limiting ve JWT doğrulama ile güvence altına alma rehberi. Symfony 7.3 güvenlik özellikleri ve mülakat soruları. - Published: 2026-09-14 - Updated: 2026-09-14 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Symfony REST API güvenliği, kimlik doğrulama, yetkilendirme ve trafik kontrolünü birleştiren katmanlı bir yaklaşım gerektirir. Symfony 7.3, RFC 7662 aracılığıyla yerel OAuth2 token introspection desteği sunarken, RateLimiter bileşeni kötüye kullanıma karşı yerleşik koruma sağlar. > **Symfony API'leri için Temel Güvenlik Katmanları** > > Üretime hazır bir Symfony API üç savunma katmanına ihtiyaç duyar: kimlik doğrulama (kim çağırıyor), yetkilendirme (neye erişebilir) ve rate limiting (ne sıklıkta). Herhangi bir katmanın eksikliği uygulamayı credential stuffing, veri sızıntısı veya hizmet reddi saldırılarına maruz bırakır. ## Symfony 7.3'te OAuth2 Token Introspection Symfony 7.3, [OAuth2 Token Introspection (RFC 7662)](https://datatracker.ietf.org/doc/html/rfc7662) için yerleşik destek ekler. Bu özellik, tokenları yerel olarak çözümleme ihtiyacını ortadan kaldırarak doğrudan yetkilendirme sunucusunu sorgulayarak erişim tokenlarını doğrular. Token formatı opak olduğunda veya üçüncü taraf bir kimlik sağlayıcısı tarafından kontrol edildiğinde bu önemlidir. `AccessTokenHandler` yapılandırması bir introspection endpoint'i kabul eder: ```yaml # config/packages/security.yaml security: firewalls: api: pattern: ^/api stateless: true access_token: token_handler: introspection: client_id: '%env(OAUTH_CLIENT_ID)%' client_secret: '%env(OAUTH_CLIENT_SECRET)%' introspection_url: '%env(OAUTH_INTROSPECTION_URL)%' ``` Introspection yanıtı `active`, `scope`, `client_id` ve isteğe bağlı olarak `username` içerir. Symfony bunları otomatik olarak güvenlik özniteliklerine eşler. ```php // src/Controller/Api/ProfileController.php namespace App\Controller\Api; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route('/api/profile', methods: ['GET'])] #[IsGranted('ROLE_USER')] class ProfileController extends AbstractController { public function __invoke(): JsonResponse { // Token zaten introspection ile doğrulandı $user = $this->getUser(); return $this->json([ 'id' => $user->getId(), 'email' => $user->getEmail(), 'scopes' => $user->getRoles(), ]); } } ``` Bu, JWT imza doğrulama yükünü uygulamadan yetkilendirme sunucusuna aktarır. Yetkilendirme sunucusu anahtar rotasyonu, token iptali ve kapsam doğrulamasını üstlenir. ## RateLimiter Bileşeni ile Rate Limiting Uygulaması [RateLimiter bileşeni](https://symfony.com/doc/current/rate_limiter.html), token bucket veya sliding window algoritmaları kullanarak endpoint'leri kötüye kullanıma karşı korur. Yapılandırma `framework.yaml` içinde yapılır: ```yaml # config/packages/framework.yaml framework: rate_limiter: # Genel API limiti: dakikada 100 istek api_limiter: policy: sliding_window limit: 100 interval: '1 minute' # Kimlik doğrulama endpoint'leri için daha sıkı limit login_limiter: policy: token_bucket limit: 5 rate: { interval: '1 minute', amount: 5 } ``` Rate limiting, bir event subscriber kullanarak controller'lara uygulanabilir: ```php // src/EventSubscriber/RateLimitSubscriber.php namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\RateLimiter\RateLimiterFactory; final class RateLimitSubscriber implements EventSubscriberInterface { public function __construct( private readonly RateLimiterFactory $apiLimiter, ) {} public static function getSubscribedEvents(): array { return [KernelEvents::REQUEST => ['onRequest', 10]]; } public function onRequest(RequestEvent $event): void { if (!$event->isMainRequest()) { return; } $request = $event->getRequest(); // Sadece API rotalarına uygula if (!str_starts_with($request->getPathInfo(), '/api')) { return; } // Limiter anahtarı olarak istemci IP veya kimliği doğrulanmış kullanıcı kullan $key = $request->getClientIp(); $limiter = $this->apiLimiter->create($key); if (!$limiter->consume()->isAccepted()) { throw new TooManyRequestsHttpException(); } } } ``` Kimliği doğrulanmış API'ler için, tek bir kötüye kullanan kullanıcının aynı ağdan gelen meşru trafiği etkilemesini önlemek amacıyla IP tabanlı anahtar yerine kullanıcı tanımlayıcısı kullanılabilir. ## Harici Bağımlılık Olmadan JWT Doğrulama Yetkilendirme sunucusu bilinen bir genel anahtarla JWT'ler verdiğinde, Symfony `OidcUserInfoTokenHandler` kullanarak tokenları yerel olarak doğrulayabilir: ```yaml # config/packages/security.yaml security: firewalls: api: pattern: ^/api stateless: true access_token: token_handler: oidc_user_info: base_uri: '%env(OIDC_ISSUER)%' claim: email ``` OIDC sağlayıcısı olmayan kendi JWT'leriniz için `lexik/jwt-authentication-bundle` kullanılabilir: ```php // src/Security/JwtTokenAuthenticator.php namespace App\Security; use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; final class JwtTokenAuthenticator implements AccessTokenHandlerInterface { public function __construct( private readonly JWTTokenManagerInterface $jwtManager, ) {} public function getUserBadgeFrom(string $accessToken): UserBadge { // Otomatik olarak çözer ve imzayı doğrular $payload = $this->jwtManager->parse($accessToken); return new UserBadge($payload['sub']); } } ``` JWT bundle, RS256/ES256 imza doğrulaması, süre sonu kontrolü ve yayıncı doğrulamasını üstlenir. Genel anahtar `config/jwt/public.pem` içinde saklanmalı ve `lexik_jwt_authentication.yaml` içinde referans verilmelidir. ## Voter'lar ile API Endpoint'lerini Güvence Altına Alma Symfony Voter'lar, basit rol kontrollerinin ötesinde ayrıntılı yetkilendirme sağlar. Yaygın bir desen, kaynak sahipliğini kontrol eder: ```php // src/Security/Voter/ArticleVoter.php namespace App\Security\Voter; use App\Entity\Article; use App\Entity\User; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; final class ArticleVoter extends Voter { public const EDIT = 'ARTICLE_EDIT'; public const DELETE = 'ARTICLE_DELETE'; protected function supports(string $attribute, mixed $subject): bool { return in_array($attribute, [self::EDIT, self::DELETE], true) && $subject instanceof Article; } protected function voteOnAttribute( string $attribute, mixed $subject, TokenInterface $token ): bool { $user = $token->getUser(); if (!$user instanceof User) { return false; } /** @var Article $article */ $article = $subject; // Yöneticiler her şeyi yapabilir if (in_array('ROLE_ADMIN', $user->getRoles(), true)) { return true; } // Yazarlar kendi makalelerini düzenleyebilir/silebilir return $article->getAuthor() === $user; } } ``` Controller'larda voter kullanımı: ```php #[Route('/api/articles/{id}', methods: ['PUT'])] public function update(Article $article, Request $request): JsonResponse { $this->denyAccessUnlessGranted(ArticleVoter::EDIT, $article); // Güncelleme mantığı } ``` Voter'lar yetkilendirme mantığını merkezileştirir ve test edilebilir hale getirir. Ayrıca güvenlik bileşeni hakkındaki [Symfony mülakat sorularında](/technologies/symfony/interview-questions/events-subscribers) sıklıkla karşılaşılır. ## Yaygın API Güvenlik Açıkları ve Çözümleri [OWASP API Security Top 10](https://owasp.org/API-Security/editions/2023/en/0x11-t10/), API'lerde tekrarlayan güvenlik açıklarını tanımlar. Symfony birçoğuna karşı yerleşik koruma sağlar: | Güvenlik Açığı | Symfony Koruması | |----------------|------------------| | Broken Object Level Authorization | Sahiplik kontrollü Voter'lar | | Broken Authentication | Giriş throttling, güvenli şifre hash'leme | | Excessive Data Exposure | DTO serileştirme grupları | | Lack of Rate Limiting | RateLimiter bileşeni | | Mass Assignment | Form doğrulama, DTO eşleme | | Security Misconfiguration | Symfony security checker, ortam değişkenleri | Mass assignment koruması için entity'ler asla doğrudan istek verilerinden hydrate edilmemelidir: ```php // src/Dto/CreateArticleDto.php namespace App\Dto; use Symfony\Component\Validator\Constraints as Assert; final class CreateArticleDto { public function __construct( #[Assert\NotBlank] #[Assert\Length(max: 255)] public readonly string $title, #[Assert\NotBlank] public readonly string $content, // Kasıtlı olarak çıkarıldı: author, createdAt, status // Bunlar uygulama tarafından ayarlanır, istemci tarafından değil ) {} } ``` DTO beyaz liste yaklaşımı, istemcilerin `isAdmin` veya `createdAt` gibi kontrol etmemeleri gereken alanları ayarlamasını engeller. ## API Tüketicileri için CORS Yapılandırması Cross-Origin Resource Sharing başlıkları, hangi domain'lerin API'yi tarayıcılardan çağırabileceğini kontrol eder. `nelmio/cors-bundle`, bildirimsel yapılandırma sağlar: ```yaml # config/packages/nelmio_cors.yaml nelmio_cors: defaults: allow_origin: ['%env(CORS_ALLOW_ORIGIN)%'] allow_methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] allow_headers: ['Content-Type', 'Authorization'] max_age: 3600 paths: '^/api/': origin_regex: true allow_origin: ['^https://.*\.example\.com$'] allow_credentials: true ``` `allow_origin: ['*']` ile `allow_credentials: true` kombinasyonundan kaçınılmalıdır. Bu kombinasyon, API'yi kötü niyetli siteler aracılığıyla kimlik bilgisi hırsızlığına maruz bırakır. Açık domain beyaz listeleri veya regex kalıpları tercih edilmelidir. ## Symfony API Güvenliği Teknik Mülakat Soruları Bu sorular, kıdemli Symfony geliştirici mülakatlarında sıklıkla karşılaşılır. Cevaplar Symfony 7.3 yeteneklerini yansıtır. **S: Symfony OAuth2 erişim token doğrulamasını nasıl yönetir?** Symfony 7.3 üç yaklaşımı destekler: imza doğrulamalı yerel JWT doğrulama, OIDC user info endpoint çağrıları ve [RFC 7662 token introspection](https://symfony.com/blog/new-in-symfony-7-3-security-improvements). Introspection, opak tokenlar veya uygulamanın yetkilendirme sunucusunu kontrol etmediği senaryolar için uygundur. `AccessTokenHandler` üçünü de birleşik bir arayüz arkasında soyutlar. **S: Symfony'de firewall'lar ve access control arasındaki fark nedir?** Firewall'lar, URL kalıpları için kimlik doğrulama mekanizmalarını tanımlar. Access control kuralları, kimlik doğrulama başarılı olduktan sonra yetkilendirme gereksinimlerini tanımlar. Bir firewall geçerli bir JWT gerektirebilirken, access control `/api/admin/*` için `ROLE_ADMIN` gerektirebilir. Sıralı olarak çalışırlar: firewall kimlik doğrular, sonra access control yetkilendirir. **S: Giriş endpoint'ine brute force saldırılarını nasıl önlersiniz?** Symfony'nin yerleşik giriş throttling'i, kullanıcı adı ve IP başına başarısız denemeleri sınırlar. Firewall'da `login_throttling` yapılandırması: ```yaml security: firewalls: main: login_throttling: max_attempts: 5 interval: '15 minutes' ``` API kimlik doğrulaması için, token endpoint'inde RateLimiter bileşeni ile birleştirilmelidir. Çoklu instance dağıtımları için deneme sayaçları Redis'te saklanmalıdır. **S: Symfony Voter'ları açıklayın ve basit rol kontrollerine göre ne zaman kullanılmalıdır.** Voter'lar, yalnızca kullanıcı rolüne değil, kaynağa bağlı karmaşık yetkilendirme mantığı uygular. Voter'lar şu durumlarda kullanılmalıdır: kullanıcı kaynağın sahibi olmalıdır, kaynak bir durum makinesine sahiptir (taslak vs yayınlanmış) veya yetkilendirme iş kurallarına bağlıdır (abonelik seviyesi). Rol kontrolleri "sadece yöneticiler ayarlara erişebilir" gibi statik izinler için yeterlidir. Daha fazla Symfony güvenlik sorusu için [Symfony mülakat hazırlık rehberine](/blog/symfony/symfony-interview-questions) bakılabilir. ## Güvenli Symfony API Oluşturma: Temel Çıkarımlar - Token formatı opak olduğunda üçüncü taraf kimlik sağlayıcıları için OAuth2 token introspection yapılandırılmalıdır - Derinlemesine savunma için hem altyapı düzeyinde (reverse proxy) hem de uygulama düzeyinde (RateLimiter bileşeni) rate limiting uygulanmalıdır - Kaynak düzeyinde yetkilendirme için Voter'lar kullanılmalı, rol kontrolleri statik izinler için ayrılmalıdır - Mass assignment'ı önlemek için istek verileri açık özelliklere sahip DTO'lara eşlenmelidir - Gizli bilgiler ortam değişkenlerinde saklanmalı, asla sürüm kontrolüne commit edilen `config/*.yaml` dosyalarında bulunmamalıdır - Güvenlik kuralları, hem izin verilen hem de reddedilen erişimi doğrulayan `WebTestCase` fonksiyonel testleri ile test edilmelidir - CI pipeline'larında `symfony security:check` ile bağımlılıklar denetlenmelidir --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/symfony/symfony-rest-api-security-oauth2-rate-limiting-2026