Bu makalede, web uygulamalarında gerçek zamanlı veri iletişimini uygulamak için teknolojilerden biri olan Sunucu Santili Olayları (SSE) açıklayacağım. SSE’nin temel kavramlarını ve operasyonel mekanizmalarını araştıracağız, diğer teknolojilerle karşılaştıracağız ve üretim ortamlarında dikkate alınması gereken güvenlik geliştirme önlemlerini tartışacağız.
Sunucuya gönderen olaylar (SSE) nedir?
Sunucu tarafından gönderilen olaylar, adından da anlaşılacağı gibi, sunucunun istemciye olay gönderdiği bir teknolojidir. Bir tarayıcı sunucuya bağlantı istediğinde, sunucu tek yönlü bir iletişim yönteminde istemciye gerekli verileri eşzamansız olarak iterken bu bağlantıyı korur.
SSE, ek protokoller uygulamadan mevcut web altyapısını kullanma avantajını sunan HTTP protokolüne dayanarak çalışır. Temel amacı, sunucudan istemciye gerçek zamanlı veri akışı, bildirimler, gerçek zamanlı beslemeler, durum güncellemeleri ve daha fazlası için yaygın olarak kullanılır.
Nasıl Çalışır
SSE’nin çalışma prensibi nispeten basittir. İstemci ve sunucu arasındaki etkileşim bu akışı izler:
- Müşteri bağlantısı: İstemci, JavaScript’i kullanarak sunucudaki belirli bir uç noktaya bağlantı ister.
EventSource
nesne. - Sunucu Yanıtı: Sunucu bu isteği ayarlayarak yanıt verir.
Content-Type
başlıktext/event-stream
. Bu başlık, istemciye iletilecek verilerin bir olay akışı olacağını bildirir. - Kalıcı bağlantı: Sunucu bağlantıyı sürekli olarak açık tutar.
- Veri Push: Yeni veri veya olaylar gerçekleştiğinde, sunucu istemciye belirli bir biçimde mesaj gönderir. Bu bağlantı, sunucu veya istemci tarafından açıkça kapatılana kadar korunur.
sequenceDiagram participant Client participant Server Client->>Server: new EventSource('/events') Note over Client,Server: Initial HTTP Request Server-->>Client: HTTP 200 OK
Content-Type: text/event-stream
Connection: keep-alive Note over Client,Server: Connection Established loop Real-time Events Server-->>Client: data: Some new data\n\n Server-->>Client: event: notification
data: {"user":"guest","message":"Welcome!"}\n\n Server-->>Client: data: Another update\n\n end Client->>Server: eventSource.close() Note over Client,Server: Connection Closed by Client
Olay akışı biçimi
Sunucu tarafından iletilen veriler basit bir metin akışıdır, her mesaj bir veya daha fazla key: value
alanlar ve iki yeni hat karakter (\n\n
). Ana alanlar şunları içerir:
data
: Aktarılacak gerçek veriler. Çokludata
Alanlar bir mesaja dahil edilebilir.event
: Olay türünü belirten bir alan. Müşteriler bu değeri belirli olay türlerini dinlemek için kullanabilir. Belirtilmezse, birmessage
etkinlik.id
: Her olay için benzersiz bir kimlik. Bir istemci sunucuya yeniden bağlandığında,id
son alınan etkinliğinLast-Event-ID
Kayıp verileri kurtarmak için başlık.retry
: Milisaniye cinsinden, müşterinin yeniden bağlanmaya çalışmadan önce beklemesi gereken zamanı belirtir.
// Simple message
data: This is a message.
// JSON data with a custom event type
event: user_update
data: {"username": "hahwul", "status": "online"}
// Message with an ID for synchronization
id: msg1
data: Some data stream
SSE ve WebSockets vs.
SSE’nin yanı sıra, yoklama, uzun süren ve WebSocks gibi gerçek zamanlı web iletişimlerini uygulamak için başka teknolojiler de var. Her teknolojinin farklı özellikleri, artıları ve eksileri vardır, bu nedenle çözmeye çalıştığınız soruna dayanarak uygun olanı seçmelisiniz.
Özellik | Oy kullanma | Uzun süren | SSE (Sunucu Santimli Etkinlikler) | WebSockets |
---|---|---|---|---|
Yön | İstemci -> Sunucu | İstemci -> Sunucu | Sunucu -> İstemci (tek yönlü) | Çift yönlü |
Protokol | HTTP | HTTP | HTTP | WebSocket (ws:// – wss:// ) |
Bağlantı | İstek başına yeni bağlantı | Uzun ömürlü, o zaman yeni | Tek Kalıcı Bağlantı | Tek Kalıcı Bağlantı |
Tepe | Yüksek | Orta | Düşük | Düşük (el sıkışmasından sonra) |
Kullanım Kılıfı | Nadir güncellemeler | Gecikmeli güncellemeler | Bildirimler, canlı yayınlar | Sohbet, oyun, işbirliği |
Yeniden bağlama | Manuel | Manuel | Otomatik (yerleşik) | Manuel |
- Oy kullanma: İstemcinin sunucudan verileri düzenli aralıklarla talep ettiği en basit yöntem, ancak gereksiz birçok istek nedeniyle verimsizdir.
- WebSockets: Çift yönlü iletişimi destekler ve çok düşük gecikme ile veri alışverişi yapabilir. Müşteri ve sunucu arasındaki etkileşimin sık olduğu sohbet veya gerçek zamanlı çevrimiçi oyunlar gibi uygulamalar için idealdir. Ancak, HTTP’den farklı bir protokol kullanır.
- SSE: Sunucudan istemciye iten tek yönlü veri gerektiğinde en uygun olanı. HTTP kullandığı için uygulanması kolaydır ve
EventSource
API, dahili otomatik yeniden bağlantı özelliklerine sahiptir, bu da onu güvenilir hale getirir.
Müşteri tarafı uygulaması
Müşteri tarafı uygulaması çok basit bir şekilde yazılabilir. EventSource
API.
const eventSource = new EventSource('/stream');
// General message listener
eventSource.onmessage = (event) => {
console.log('New message:', event.data);
};
// Listener for custom events
eventSource.addEventListener('notification', (event) => {
const notificationData = JSON.parse(event.data);
console.log('Notification:', notificationData.message);
});
// Error handling
eventSource.onerror = (err) => {
console.error("EventSource failed:", err);
// EventSource will automatically try to reconnect.
// To close it permanently:
// eventSource.close();
};
SSE nasıl güvence altına alınır
SSE HTTP üzerinde çalıştığından, ortak web güvenlik tehditlerine maruz kalır. Bu nedenle, SSE’yi bir üretim ortamında kullanırken güvenlik dikkate alınmalıdır.
Kimlik Doğrulama ve Yetkilendirme
. EventSource
API, özel HTTP başlıklarını ayarlamayı standart olarak desteklemez. Authorization
. Bu, tipik token tabanlı kimlik doğrulama için kısıtlamalar oluşturur.
- Çerez tabanlı kimlik doğrulama: Tarayıcı, bir yaparken otomatik olarak çerez gönderir
EventSource
İstek, bu nedenle oturum çerez tabanlı kimlik doğrulama doğal olarak çalışır. Bu en basit ve en etkili yöntemlerden biridir. - Sorgu Parametre Jetonu: URL sorgu parametreleri aracılığıyla bir kimlik doğrulama jetonunu geçmek de mümkündür (
/stream?token=...
). Ancak, bu yöntem sunucu günlüklerinde, tarayıcı geçmişinde vb. Jeton açığa çıkma riskiyle karşı karşıya kalır, bu nedenle dikkatli bir şekilde kullanılmalıdır.
CSRF (Siteler Arası Talep Arıtma)
SSE bağlantıları bir GET isteği ile başlar, böylece CSRF saldırılarına karşı savunmasız olabilirler. Bir saldırgan, bir kullanıcıyı giriş yaparken kötü amaçlı bir sayfayı ziyaret etmek için kandırabilir, kullanıcının ayrıcalıklarını kullanarak bir SSE bağlantısı kurabilir ve hassas gerçek zamanlı verileri çalabilir.
- Origin başlık kontrolü: Sunucu
Origin
Yalnızca yetkili alanlardan gelenlere izin verme isteklerinin başlığı. - Samesite çerezleri:
SameSite=Lax
veyaSameSite=Strict
Kimlik doğrulama çerezlerine öznitelik, istekler farklı kökenlerden geldiğinde çerezlerin gönderilmesini önler.
XSS (siteler arası komut dosyası)
Sunucu tarafından gönderilen veriler doğrudan istemci tarafında HTML’ye oluşturulursa, bir XSS güvenlik açığı oluşabilir. Sunucudan alınan veriler asla güvenilmemeli ve kullanımdan önce her zaman kaçmalı veya kodlanmalıdır.
const outputDiv = document.getElementById('output');
eventSource.onmessage = (event) => {
// Vulnerable to XSS: Never do this!
// outputDiv.innerHTML += event.data + '
';
// Safe: Use textContent to render data as plain text.
const p = document.createElement('p');
p.textContent = event.data;
outputDiv.appendChild(p);
};
Taşıma Güvenliği
Ortadaki insan (MITM) saldırıları yoluyla olay akışlarının maruz kalmasını veya değiştirilmesini önlemek için, SSE iletişimleri yoluyla şifrelenmelidir. HTTPS. Bu isteğe bağlı değil, gereklidir.
Hizmet Reddi (DOS)
SSE, uzun süreler için bağlantıları korur ve bu da hizmet saldırılarının reddedilmesi için potansiyel bir hedef haline gelir. Bir saldırgan, sunucunun kaynaklarını tüketmek için çok sayıda bağlantı oluşturabilir.
- Oran Sınırlama: Belirli bir IP adresinin veya kullanıcının oluşturabileceği eşzamanlı bağlantı sayısını sınırlamalısınız.
- Kaynak Yönetimi: Anormal trafiği kontrol etmek için Web sunucularının veya ters proxy’lerin (Nginx gibi) maksimum eşzamanlı bağlantı ayarlarını optimize edin.
Çözüm
Sunucu Santiye Etkinlikler (SSE), sunucudan istemciye gerçek zamanlı veri akışı için güçlü ve standart bir teknolojidir. HTTP’ye dayandığı için uygulamak kolaydır ve otomatik yeniden bağlanma, geliştirme ve bakımı kolaylaştırma gibi yerleşik kolaylık özelliklerine sahiptir.
Ancak, bu kolaylığın arkasında, dikkate alınması gereken güvenlik yönleri vardır. Güvenli SSE uygulaması için, kimlik doğrulama/yetkilendirme, CSRF, XSS, DOS gibi çeşitli tehditleri tanımak ve uygun savunma mekanizmalarını uygulamak çok önemlidir.
Çift yönlü iletişim gerekli olmadığı sürece, SSE, WebSoks’un karmaşıklığı olmadan gerçek zamanlı güncelleme işlevselliğini uygulayabilen yüksek verimli bir alternatiftir.