Memutus koneksi member
Otorisasi channel mengontrol subscription tetapi tidak menetapkan identitas pada tingkat koneksi. Tanpa identitas tersebut, sign-out di tempat lain tidak menutup socket yang ada atau menghapus subscription channel-nya.
Panggil signin() untuk menetapkan member_id dari backend Anda pada koneksi. Operasi disconnect kemudian dapat menutup semua koneksi yang dimiliki member tersebut pada app.
Gunakan alur ini setelah sign-out jarak jauh, pencabutan token, pemblokiran, perubahan kata sandi, atau penghapusan workspace seat.
1. Sign in koneksi
Arahkan client ke endpoint di backend Anda sendiri dan panggil signin() sekali:
import { BirdRealtime } from "@messagebird/realtime";
const bird = new BirdRealtime({
appKey: "your-app-key",
region: "us1",
memberAuthEndpoint: "/bird/auth/member",
});
const member = await bird.signin();
console.log("signed in as", member.member_id);import BirdRealtime
let bird = BirdRealtime(options: .init(
appKey: "your-app-key",
region: "us1",
memberAuthEndpoint: URL(string: "https://your-backend.example.com/bird/auth/member")
))
let member = try await bird.signin()
print("signed in as", member.memberId)import com.bird.realtime.BirdRealtime
import com.bird.realtime.BirdRealtimeOptions
val bird = BirdRealtime(
BirdRealtimeOptions(
appKey = "your-app-key",
region = "us1",
memberAuthEndpoint = "https://your-backend.example.com/bird/auth/member",
)
)
val member = bird.signin() // suspending
println("signed in as ${member.memberId}")Identitas melekat pada koneksi. Panggil signin() sekali, dan client akan sign in kembali setelah setiap reconnect.
Sign-in tidak mengotorisasi subscription channel. Channel private dan presence tetap memanggil endpoint otorisasi channel Anda. Koneksi tanpa identitas member dapat subscribe ke channel mana pun yang disetujui endpoint tersebut. Lihat Mengotorisasi channel.
2. Tanda tangani identitas dari backend Anda
Client mengirimkan connection ID dalam permintaan POST:
Contoh kode
{ "connection_id": "26896.319537" }Endpoint Anda menjawab dengan identitas sebagai JSON string, beserta tanda tangan atas string yang sama persis:
Contoh kode
{
"auth": "your-app-key:8f9a…",
"member_data": "{\"member_id\":\"u_42\",\"member_info\":{\"name\":\"Ada\"}}"
}String yang ditandatangani adalah <connection_id>::member::<member_data>, dengan dua titik dua di setiap sisi member. Lakukan HMAC-SHA256 dengan app secret, encode ke hex, dan tambahkan app key di depan:
import { createHmac } from "node:crypto";
app.post("/bird/auth/member", (req, res) => {
const { connection_id } = req.body;
// Your own decision: who is this caller, and may they connect at all?
const user = getUserFromSession(req);
if (!user) return res.sendStatus(403);
const memberData = JSON.stringify({
member_id: user.id,
member_info: { name: user.name },
});
const sig = createHmac("sha256", process.env.BIRD_REALTIME_SECRET)
.update(`${connection_id}::member::${memberData}`)
.digest("hex");
res.json({ auth: `${process.env.BIRD_REALTIME_KEY}:${sig}`, member_data: memberData });
});import hmac, hashlib, json, os
def sign_in(connection_id: str, user) -> dict:
key = os.environ["BIRD_REALTIME_KEY"]
secret = os.environ["BIRD_REALTIME_SECRET"].encode()
member_data = json.dumps({"member_id": user.id, "member_info": {"name": user.name}})
to_sign = f"{connection_id}::member::{member_data}"
sig = hmac.new(secret, to_sign.encode(), hashlib.sha256).hexdigest()
return {"auth": f"{key}:{sig}", "member_data": member_data}func signIn(connectionID string, user User) (map[string]string, error) {
key := os.Getenv("BIRD_REALTIME_KEY")
secret := []byte(os.Getenv("BIRD_REALTIME_SECRET"))
memberData, err := json.Marshal(map[string]any{
"member_id": user.ID,
"member_info": map[string]string{"name": user.Name},
})
if err != nil {
return nil, err
}
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(connectionID + "::member::" + string(memberData)))
return map[string]string{
"auth": key + ":" + hex.EncodeToString(mac.Sum(nil)),
"member_data": string(memberData),
}, nil
}function signIn(string $connectionId, User $user): array
{
$key = getenv('BIRD_REALTIME_KEY');
$secret = getenv('BIRD_REALTIME_SECRET');
$memberData = json_encode(['member_id' => $user->id, 'member_info' => ['name' => $user->name]]);
$sig = hash_hmac('sha256', "{$connectionId}::member::{$memberData}", $secret);
return ['auth' => "{$key}:{$sig}", 'member_data' => $memberData];
}Tanda tangani string member_data yang sama persis dengan yang Anda kembalikan. Serialisasi ulang objek dapat mengubah byte-nya dan membatalkan tanda tangan.
member_id adalah nilai yang ditargetkan oleh operasi disconnect. Nilai ini menerima hingga 128 karakter URL-safe, termasuk + : @ . _ -, tetapi tidak / ? # % atau spasi. Jika identifier Anda mengandung karakter yang tidak didukung, petakan ke nilai aman yang stabil sebelum menandatangani. Edge menolak member ID yang tidak valid, sehingga koneksi tidak memiliki identitas yang dapat ditargetkan oleh operasi disconnect.
member_info bersifat opsional. Untuk sign-in koneksi, nilai ini dikembalikan ke client tersebut, bukan disiarkan ke presence channel.
Identitas juga dapat membawa array watchlist berisi member id. Pada app dengan watchlist_events diaktifkan, koneksi akan diberi tahu saat member tersebut online atau offline; lihat Watchlist events.
String yang ditandatangani di sini sengaja berbeda dari string yang ditandatangani oleh subscription presence, sehingga otorisasi presence tidak pernah bisa di-replay untuk mengklaim identitas, meskipun kedua payload sama-sama disebut member_data.
3. Disconnect member
await bird.realtime.members.disconnect("rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42");client.realtime.members.disconnect("rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42")if err := client.Realtime.Members.Disconnect(context.Background(), "rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42"); err != nil {
log.Fatal(err)
}$bird->realtime->members->disconnect('rap_01krdgeqcxet5s7t44vh8rt9mg', 'u_42');curl -X POST \
https://us1.platform.bird.com/v1/realtime/apps/rap_01krdgeqcxet5s7t44vh8rt9mg/members/u_42/disconnect \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET"Operasi ini menutup semua koneksi yang sudah sign-in untuk member tersebut pada app, termasuk tab dan perangkat lain. Operasi ini tidak menutup koneksi anonim atau koneksi yang ditetapkan ke member lain.
Yang dilihat client
Koneksi ditutup dengan kode 4009 dan tidak reconnect secara otomatis:
bird.connection.bind("error", (e) => {
if (e.code === 4009) showSignedOutScreen();
});bird.onError { error in
if error.code == 4009 { showSignedOutScreen() }
}bird.onError { error ->
if (error.code == 4009) showSignedOutScreen()
}Tampilkan status signed-out saat autentikasi telah berakhir. Memanggil bird.connect() memulai koneksi baru yang sign in melalui endpoint Anda, jadi lakukan reconnect hanya setelah status otorisasi member berubah.
Kegagalan sign-in tidak menutup socket. Client melaporkan kegagalan tersebut secara terpisah dan membiarkan koneksi tanpa identitas member. Setelah reconnect, client melaporkan ini melalui signin_error karena promise signin() yang asli sudah resolved.
bird.connection.bind("signin_error", (e) => {
console.warn("connection has no identity:", e.message);
});bird.onSigninError { error in
print("connection has no identity:", error.message)
}bird.onSigninError { error ->
println("connection has no identity: ${error.message}")
}Koneksi tetap dapat menerima event dari channel yang terotorisasi, tetapi operasi member-event dan disconnect tidak dapat menargetkannya. Di browser client, bird.signedInMember bernilai null dalam status ini.
Mencegah reconnection
Operasi disconnect menutup koneksi saat ini tanpa membuat pemblokiran permanen. Client yang sama dapat terhubung kembali.
Cabut sesi atau catat pemblokiran sebelum memutus koneksi member. Endpoint otorisasi member Anda kemudian dapat mengembalikan 403 Forbidden jika client reconnect.
Langkah selanjutnya
- Mengotorisasi channel membahas tanda tangan lain yang dihitung backend Anda, untuk subscription private dan presence.
- Disconnect member adalah referensi API lengkap untuk permintaan ini.
- Mengirim event ke member adalah operasi lain yang ditujukan ke member.
- Presence channel menjelaskan mengapa satu member dapat memiliki beberapa koneksi.
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini. Sumber daya tersedia dalam bahasa Inggris.
Jelajahi kemampuannyaRealtimeIkuti jalur pembelajaranBuild your first integrationPanduan implementasiSend your first realtime event
Coba praktiknya dan dapatkan ringkasan implementasi