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ı.

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.
Ü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) 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:
# 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.
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, 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:
# 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:
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:
# config/packages/security.yaml
security:
firewalls:
api:
pattern: ^/api
stateless: true
access_token:
token_handler:
oidc_user_info:
base_uri: '%env(OIDC_ISSUER)%'
claim: emailOIDC sağlayıcısı olmayan kendi JWT'leriniz için lexik/jwt-authentication-bundle kullanılabilir:
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.
Symfony mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
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:
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ı:
#[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 sıklıkla karşılaşılır.
Yaygın API Güvenlik Açıkları ve Çözümleri
OWASP API Security Top 10, 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:
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:
# 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: trueallow_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. 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ı:
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 bakılabilir.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
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/*.yamldosyalarında bulunmamalıdır - Güvenlik kuralları, hem izin verilen hem de reddedilen erişimi doğrulayan
WebTestCasefonksiyonel testleri ile test edilmelidir - CI pipeline'larında
symfony security:checkile bağımlılıklar denetlenmelidir
Symfony kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
14 Eylül 2026 tarihinde güncellendi
Paylaş
İlgili makaleler

2026'da Symfony ile API Platform: Mimari, State Providers ve Mülakat Soruları
API Platform 4.2 ile Symfony'yi öğrenin: State Providers, Processors, Object Mapper, JSON Streamer ve performans optimizasyonları. Deneyimli geliştiriciler için sık sorulan mülakat soruları.

API Platform GraphQL Symfony: Şemalar, Mutasyonlar ve Mülakat Soruları 2026
Symfony'de API Platform ile GraphQL entegrasyonu için kapsamlı rehber. Şemalar, sorgular, mutasyonlar, resolver'lar, güvenlik ve mülakat soruları.

Symfony REST API Guvenliği: Kimlik Doğrulama, JWT ve 2026 Mulakat Soruları
Symfony REST API guvenliği icin kapsamlı rehber. JWT kimlik doğrulama, guvenlik en iyi uygulamaları ve 2026 mulakat sorularına hazırlık.