Bezpieczeństwo w czasie rzeczywistym
Twoje reguły sesji decydują, kto może subskrybować.
W Bird nie ma modelu uprawnień do konfiguracji. Prywatna subskrypcja lub subskrypcja obecności jest zatwierdzana przez endpoint, który sam tworzysz, z wykorzystaniem sesji, którą już posiadasz, i podpisana sekretem przechowywanym wyłącznie na Twoich serwerach. Bird weryfikuje podpis — Ty decydujesz o polityce.
// Your endpoint. The only place the app secret lives.
app.post("/bird/auth", async (req, res) => {
const { connection_id, channel_name } = req.body;
const user = await session(req);
if (!mayJoin(user, channel_name)) return res.sendStatus(403);
// Signs <connection_id>:<channel_name>[:<member_data>] with the app
// secret, and adds shared_secret on an encrypted channel.
res.json(
await bird.realtime.authorizeChannel({
connectionId: connection_id,
channelName: channel_name,
memberData: JSON.stringify({
member_id: user.id,
member_info: { name: user.name },
}),
}),
);
});
Jeden klucz jest publiczny. Drugi nie.
Wszystko wynika z tego podziału.
Każda aplikacja korzystająca z Bird Realtime API ma klucz i sekret. Klucz jest przeznaczony do umieszczenia w kodzie klienta; sekret uwierzytelnia wywołania Twojego serwera i podpisuje subskrypcje — jest wyświetlany tylko raz, przy tworzeniu. Każdy, kto go posiada, może publikować w Twojej aplikacji i fałszować tożsamość obecności, więc traktuj go jak hasło do bazy danych. Rotacja jest addytywna, nie destrukcyjna: utwórz drugi klucz, wdróż go, a następnie unieważnij stary.
Cztery mechanizmy kontroli, cztery pytania
Kto może subskrybować, kto może utrzymywać połączenie, kto może odczytać dane i kto nadal ma dostęp.
- 01
Podpisane subskrypcje.
Klient wysyła identyfikator połączenia i nazwę kanału do Twojego endpointu. Sprawdzasz wywołującego, odrzucasz kodem 403, jeśli nie ma prawa dołączyć, lub zwracasz podpis HMAC-SHA256 obejmujący identyfikator połączenia i nazwę kanału, poprzedzony kluczem aplikacji. Ponieważ identyfikator połączenia jest częścią podpisu, zatwierdzenie dotyczy jednego połączenia i nie może być odtworzone na innym. Kanał obecności podpisuje również tożsamość członka, i musi to być dokładnie taki ciąg znaków, jaki zwracasz: ponowna serializacja tego samego obiektu może zmienić kolejność kluczy i unieważnić podpis.
- 02
Autoryzowane połączenia.
Klucz aplikacji jest publiczny, więc każdy, kto może załadować Twoją stronę, może otworzyć z nim gniazdo. Włącz autoryzowane połączenia, a każde nowe połączenie ma 30 sekund, aby udowodnić, że ktoś posiadający sekret je poświadczył — poprzez prywatną subskrypcję lub logowanie. Wszystko, co tego nie spełni, zostaje zamknięte z kodem 4009, a nieautoryzowane połączenia nigdy nie są wliczane do Twojego limitu. Subskrypcja kanału publicznego niczego nie dowodzi i nie autoryzuje połączenia.
- 03
Szyfrowanie end-to-end.
Kanał private-encrypted- jest zabezpieczany przez Twój serwer, zanim żądanie opuści Twój proces, za pomocą 32-bajtowego klucza głównego, który nigdy nie pojawia się w żądaniu Realtime API. Każdy kanał wyprowadza własny klucz, więc autoryzacja klienta do jednego szyfrowanego kanału nie pozwala mu odczytać innego. Bird nie może odzyskać utraconego klucza, a rotacja chroni przyszłe dane, nie przeszłe.
- 04
Natychmiastowe cofnięcie dostępu.
Wylogowany użytkownik, zmienione hasło, zbanowane konto: rozłącz członka, a każde połączenie przypisane do tej tożsamości zostanie zamknięte na każdym urządzeniu. Klienci traktują to zamknięcie jako ostateczne i nie ponawiają prób, a Twoje endpointy przestają dla nich podpisywać — nie mogą wrócić.
Szyfrowane kanały
Dane, których Bird nie może odczytać, na infrastrukturze, którą Bird zarządza.
SDK serwera rozpoznaje prefiks kanału, wyprowadza klucz tego kanału z Twojego klucza głównego i szyfruje dane lokalnie. Warstwa brzegowa przekazuje szyfrogram, a Twój endpoint autoryzacyjny udostępnia wyprowadzony klucz tylko zatwierdzonym klientom. Dwa ograniczenia do uwzględnienia w projekcie: nazwy kanałów i zdarzeń są przesyłane jawnie, więc wybieraj nazwy, które nie ujawniają tego, co chronisz, a szyfrowanie nie może być łączone z obecnością ani ze zdarzeniami klienta. Buforowanie jest możliwe: kanał private-encrypted-cache- przechowuje buforowane zdarzenie w postaci zaszyfrowanej.
const bird = new BirdClient({
apiKey: process.env.BIRD_API_KEY!,
realtime: {
key: process.env.BIRD_REALTIME_KEY,
secret: process.env.BIRD_REALTIME_SECRET,
// 32 random bytes, yours alone. Never sent to Bird.
encryptionMasterKey: process.env.BIRD_REALTIME_MASTER_KEY,
},
});
// Sealed in your process. The edge forwards ciphertext.
await bird.realtime.publish(APP_ID, {
event: "order.updated",
channels: ["private-encrypted-orders"],
data: { order_id: "ord_123", status: "shipped" },
});
Czego autoryzacja nie zapewnia.
Wymaganie autoryzowanych połączeń kontroluje, kto może utrzymywać otwarte gniazdo. Nie zmienia to, kto może czytać kanał: kanał publiczny pozostaje dostępny do odczytu dla każdego autoryzowanego połączenia, więc zdarzenia należące do jednego klienta powinny trafiać na kanał prywatny, którego nazwę sprawdza Twój endpoint. A ponieważ Twoje endpointy są organem decyzyjnym, permisywny endpoint udostępnia dostęp równie swobodnie jak wyciekły klucz. Ta sama zasada dotyczy zdarzeń klienta, których warstwa brzegowa nie waliduje: używaj ich jako sygnałów, a wszystko, co ma charakter autorytatywny, kieruj przez swój serwer.
Gdzie przechowywane są dane.
Aplikacja wybiera swój region podczas tworzenia i zachowuje go na stałe, więc wybierasz ten najbliższy Twoim użytkownikom. Region aplikacji może różnić się od regionu macierzystego Twojego workspace'a. Aplikacje stanowią także granicę izolacji: dwie aplikacje nigdy nie widzą nawzajem swoich kanałów, dlatego jedna aplikacja na środowisko to właściwy sposób na oddzielenie ruchu testowego od produkcyjnego.
Zgłęb temat w dokumentacji.
Autoryzacja kanałów opisuje kontrakt żądania i odpowiedzi oraz dokładny ciąg do podpisania. Wymaganie autoryzowanych połączeń obejmuje 30-sekundowe okno i kod 4009, szyfrowane kanały opisują generowanie i rotację kluczy, a kończenie połączeń członków to przepływ logowania i rozłączania.
Zastosuj w praktyce.
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Reszta Realtime
Jedna aplikacja, jedna para kluczy. Odkryj pozostałe możliwości.
Wyślij klucz. Zachowaj sekret.
Podpisane subskrypcje, autoryzowane połączenia i szyfrowane kanały są częścią każdej aplikacji Realtime, w każdym planie.