चैनलों को अधिकृत करना
ऐप कुंजी रखने वाला कोई भी क्लाइंट पब्लिक चैनलों को सब्सक्राइब कर सकता है। दो चैनल-नाम प्रीफ़िक्स के लिए आपके बैकएंड को सब्सक्रिप्शन अधिकृत करना होता है। आपको चैनल अलग से कॉन्फ़िगर नहीं करने पड़ते।
private-… नाम वाले चैनल में हर सब्सक्रिप्शन को आपके बैकएंड की स्वीकृति चाहिए। presence-… नाम वाला चैनल भी यही करता है और साथ ही सब्सक्राइबर से एक पहचान जोड़ता है, ताकि चैनल पर मौजूद हर व्यक्ति देख सके कि वहाँ और कौन है। कोई भी अन्य नाम पब्लिक होता है।
ऐप सीक्रेट केवल आपके बैकएंड के पास होता है। क्लाइंट आपके सर्वर से किसी खास सब्सक्रिप्शन पर हस्ताक्षर करने को कहता है, और Realtime एज उसे स्वीकार करने से पहले उस हस्ताक्षर की जाँच करता है। आपका सर्वर क्लाइंट को सीक्रेट दिखाए बिना तय करता है कि कॉलर सब्सक्राइब कर सकता है या नहीं।
क्लाइंट को अपने एंडपॉइंट की ओर इंगित करें
क्लाइंट को अपने बैकएंड पर एक authEndpoint दें:
import { BirdRealtime } from "@messagebird/realtime";
const bird = new BirdRealtime({
appKey: "your-app-key",
region: "us1",
authEndpoint: "/bird/auth",
});
const room = bird.subscribe("presence-room-1");import BirdRealtime
let bird = BirdRealtime(options: .init(
appKey: "your-app-key",
region: "us1",
authEndpoint: URL(string: "https://your-backend.example.com/bird/auth")
))
let room = bird.subscribe("presence-room-1")import com.bird.realtime.BirdRealtime
import com.bird.realtime.BirdRealtimeOptions
val bird = BirdRealtime(
BirdRealtimeOptions(
appKey = "your-app-key",
region = "us1",
authEndpoint = "https://your-backend.example.com/bird/auth",
)
)
val room = bird.subscribe("presence-room-1")क्लाइंट हर प्राइवेट या प्रेज़ेंस सब्सक्रिप्शन के लिए इस एंडपॉइंट को कॉल करता है, जिसमें दोबारा कनेक्ट होने के बाद बहाल किए गए सब्सक्रिप्शन भी शामिल हैं। प्राधिकरण एक ही कनेक्शन पर लागू होता है, क्योंकि हस्ताक्षर में उसकी कनेक्शन ID शामिल होती है।
ब्राउज़र क्लाइंट को डिफ़ॉल्ट रूप से same-origin एंडपॉइंट चाहिए। cross-origin authEndpoint इस्तेमाल करने के लिए allowCrossOriginAuth: true सेट करें। ब्राउज़र क्लाइंट कॉन्फ़िगर किए गए authHeaders केवल same-origin एंडपॉइंट को भेजता है।
आपका एंडपॉइंट क्या प्राप्त करता है और क्या लौटाता है
क्लाइंट JSON को POST करता है:
{ "connection_id": "26896.319537", "channel_name": "presence-room-1" }सिग्नेचर के साथ जवाब दें:
{ "auth": "your-app-key:8f9a…" }प्रेज़ेंस चैनल के लिए सदस्य की पहचान भी JSON स्ट्रिंग के रूप में लौटाएँ, ठीक वही स्ट्रिंग जिस पर आपने साइन किया था:
{
"auth": "your-app-key:8f9a…",
"member_data": "{\"member_id\":\"u_42\",\"member_info\":{\"name\":\"Ada\"}}"
}member_id वह पहचान है जो दूसरे सदस्य देखते हैं, और डिस्कनेक्ट ऑपरेशन इसी मान को लक्षित करता है। member_info वैकल्पिक JSON डेटा है, जो चैनल के हर सदस्य को भेजा जाता है। इसकी सीमा 1 KB है, इसलिए इसमें केवल छोटा और गैर-संवेदनशील प्रोफ़ाइल डेटा रखें।
इस एंडपॉइंट में कॉलर को उसकी सेशन कुकी या बेयरर टोकन से अधिकृत करें। अगर कॉलर को चैनल से नहीं जुड़ना चाहिए, तो 403 Forbidden लौटाएँ। प्रेज़ेंस चैनलों के लिए पहचान उसी जवाब में तय करें।
वह स्ट्रिंग जिस पर आप साइन करते हैं
हिस्सों को कोलन से जोड़ें, फिर ऐप सीक्रेट के साथ HMAC-SHA256 निकालें और नतीजे को हेक्स में एन्कोड करें। नतीजे के आगे ऐप कुंजी और एक कोलन लगाएँ।
| चैनल का प्रकार | साइन की जाने वाली स्ट्रिंग |
|---|---|
private-… | <connection_id>:<channel_name> |
private-encrypted-… | <connection_id>:<channel_name> |
presence-… | <connection_id>:<channel_name>:<member_data> |
प्रेज़ेंस चैनलों के लिए, ठीक वही member_data स्ट्रिंग साइन करें जो आप लौटाते हैं। उसी ऑब्जेक्ट को दोबारा सीरियलाइज़ करने से उसकी कुंजियों का क्रम या स्पेसिंग बदल सकती है और सिग्नेचर अमान्य हो सकता है।
एन्क्रिप्टेड चैनल प्राइवेट चैनल की तरह ही साइन होता है, और उसका ऑथ रिस्पॉन्स साथ में चैनल की डिक्रिप्शन कुंजी को shared_secret के रूप में भी लौटाता है। SDK हेल्पर इसे अपने-आप जोड़ देता है; कुंजी कैसे बनती है और चैनल कैसे व्यवहार करता है, यह एन्क्रिप्टेड चैनल में बताया गया है।
हर सर्वर SDK में एक authorizeChannel हेल्पर होता है। यह कॉन्फ़िगर किए गए ऐप क्रेडेंशियल से साइन करता है और कोई नेटवर्क अनुरोध किए बिना रिस्पॉन्स बॉडी लौटाता है। एन्क्रिप्टेड चैनलों के लिए हेल्पर shared_secret भी जोड़ता है।
app.post("/bird/auth", async (req, res) => {
const { connection_id, channel_name } = req.body;
// Your own authorization decision goes here.
const user = getUserFromSession(req);
if (!user || !mayJoin(user, channel_name)) return res.sendStatus(403);
const memberData = channel_name.startsWith("presence-")
? JSON.stringify({ member_id: user.id, member_info: { name: user.name } })
: undefined;
res.json(
await bird.realtime.authorizeChannel({
connectionId: connection_id,
channelName: channel_name,
memberData,
}),
);
});import json
@app.post("/bird/auth")
def bird_auth():
body = request.get_json()
channel_name = body["channel_name"]
# Your own authorization decision goes here.
user = get_user_from_session()
if user is None or not may_join(user, channel_name):
abort(403)
member_data = None
if channel_name.startswith("presence-"):
member_data = json.dumps({"member_id": user.id, "member_info": {"name": user.name}})
return client.realtime.authorize_channel(
connection_id=body["connection_id"],
channel_name=channel_name,
member_data=member_data,
)func birdAuth(w http.ResponseWriter, r *http.Request) {
var body struct {
ConnectionID string `json:"connection_id"`
ChannelName string `json:"channel_name"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
// Your own authorization decision goes here.
user, ok := userFromSession(r)
if !ok || !mayJoin(user, body.ChannelName) {
http.Error(w, "forbidden", http.StatusForbidden)
return
}
params := bird.RealtimeChannelAuthorizationParams{
ConnectionID: body.ConnectionID,
ChannelName: body.ChannelName,
}
if strings.HasPrefix(body.ChannelName, "presence-") {
memberData, _ := json.Marshal(map[string]any{
"member_id": user.ID,
"member_info": map[string]string{"name": user.Name},
})
params.MemberData = string(memberData)
}
auth, err := client.Realtime.AuthorizeChannel(params)
if err != nil {
http.Error(w, "authorization failed", http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(auth)
}function birdAuth(string $connectionId, string $channelName, User $user): array
{
// Your own authorization decision goes here.
if (!mayJoin($user, $channelName)) {
http_response_code(403);
exit;
}
$memberData = null;
if (str_starts_with($channelName, 'presence-')) {
$memberData = json_encode(['member_id' => $user->id, 'member_info' => ['name' => $user->name]]);
}
return $bird->realtime->authorizeChannel($connectionId, $channelName, $memberData);
}जिस भाषा में SDK नहीं है, उसमें भी साइनिंग का नियम वही है: ऐप सीक्रेट से स्ट्रिंग का HMAC-SHA256 निकालें, उसे हेक्स-एनकोड करें, और उसके आगे ऐप कुंजी और एक कोलन जोड़ें।
मेंबर और कनेक्शन
मेंबर एक पहचान है, जबकि कनेक्शन एक खुला WebSocket है। अगर कोई आपका ऐप तीन टैब में खोलता है, तो एक मेंबर के तीन कनेक्शन होते हैं। पहला कनेक्शन सब्सक्राइब करने पर member_added फ़ायर होता है, और आख़िरी कनेक्शन के छोड़ने पर member_removed फ़ायर होता है। बाकी कनेक्शन चैनल की कनेक्शन संख्या बदलते हैं, पर उनसे मेंबर इवेंट नहीं बनते।
आम विफलताएँ
अस्वीकृत सब्सक्रिप्शन क्लाइंट त्रुटि के रूप में आता है। इन आम कारणों की जाँच करें:
- अमान्य सिग्नेचर। आपने जो स्ट्रिंग साइन की, वह मेल नहीं खाती। लगभग हमेशा इसका कारण दोबारा सीरियलाइज़ किया गया
member_dataहोता है, या ऐसा सिग्नेचर जो चैनल नाम केprivate-याpresence-प्रीफ़िक्स के बिना निकाला गया हो। - अमान्य कुंजी।
authमें दी गई कुंजी किसी दूसरे ऐप की है, या रद्द कर दी गई है। कुंजियाँ बदलते समय क्लाइंट कीappKeyऔर वह सीक्रेट, जिससे आपका एंडपॉइंट साइन करता है, दोनों अपडेट करें। - सदस्य डेटा मौजूद नहीं है। एक प्रेज़ेंस सब्सक्रिप्शन
member_dataके बिना पहुँचा। प्रेज़ेंस चैनलों से गुमनाम रूप से नहीं जुड़ा जा सकता। - आपके अपने एंडपॉइंट से
403। आपके ऑथराइज़ेशन निर्णय ने अनुरोध अस्वीकार कर दिया। जिस उपयोगकर्ता को चैनल से जुड़ने की अनुमति नहीं है, उसके लिए यही अपेक्षित परिणाम है।
अगले कदम
- अपना पहला रियलटाइम इवेंट भेजें शुरू से अंत तक की वह गाइड है जिस पर यह गाइड आधारित है।
- एन्क्रिप्टेड चैनल इसी सिग्नेचर का उपयोग करके स्वीकृत सब्सक्राइबरों को डिक्रिप्शन कुंजी भी देते हैं।
- प्रेज़ेंस चैनल में सदस्य सूची, सदस्य इवेंट और आपके सर्वर से प्रेज़ेंस पढ़ने की जानकारी है।
- सदस्य कनेक्शन समाप्त करना वह दूसरा सिग्नेचर है जिसे आपका बैकएंड बनाता है, और इसी से आप किसी सदस्य के कनेक्शन बंद कर सकते हैं।
- वेबहुक और इवेंट में आपके अपने एंडपॉइंट पर मिलने वाले
realtime.*इवेंट की जानकारी है, जिनमें सदस्यों का जुड़ना और छोड़ना शामिल है।
संबंधित संसाधन
इस विषय के लिए दस्तावेज़, गाइड और उदाहरणों के साथ आगे बढ़ें।