दस्तावेज़

पहचान सत्यापन

किसी साइन-इन किए हुए व्यक्ति को पहचानें और आपके backend द्वारा नियंत्रित एक सिग्नेचर का उपयोग करके डिवाइसों के आर-पार उनका बातचीत-इतिहास बहाल करें।

सत्यापन क्यों करें#

डिफ़ॉल्ट रूप से SDK एनॉनिमस होता है: यह एक स्थिर visitor_id जनरेट करता है और उसे प्लेटफ़ॉर्म कीस्टोर में रखता है। एक डिवाइस पर एक बातचीत के लिए यह पर्याप्त है। किसी विशिष्ट यूज़र को पहचानने, री-लॉगिन या दूसरे डिवाइस पर इतिहास बहाल करने, और किसी बातचीत को किसी कॉन्टैक्ट प्रोफ़ाइल से भरोसेमंद ढंग से बाँधने के लिए, backend को इस बात का प्रमाण चाहिए कि क्लाइंट वही है जो वह होने का दावा करता है। अगर SDK बस «मैं यूज़र 42 हूँ» भेज देता, तो कोई भी दूसरी id की नक़ल कर सकता था और किसी और की चैट पढ़ सकता था — इसलिए Respondo एक क्रिप्टोग्राफ़िक सिग्नेचर, userHash की माँग करता है, जिसे केवल आपका backend बना सकता है।

identity secret प्राप्त करना#

identity_secret एक गुप्त स्ट्रिंग है जो आपके एजेंट (वह AI वर्कर जिससे आपका विजेट चैनल जुड़ा है) से बँधी होती है। इसे डैशबोर्ड में यहाँ जनरेट करें: Channels → Widget → Identity verification। चूँकि यह एजेंट पर रहता है, उस एजेंट से चलने वाला हर चैनल — वेब विजेट और मोबाइल SDK दोनों — वही secret साझा करता है। यह पहचानों पर हस्ताक्षर करने का अधिकार देता है, इसलिए इसे केवल आपके backend पर रहना चाहिए और इसे कभी ऐप में नहीं भेजा जाना चाहिए।

userHash फ़ॉर्मूला#

userHash एक अकेली हस्ताक्षरित पहचान-स्ट्रिंग पर HMAC-SHA256 है, जो लोअरकेस hex के रूप में एन्कोडेड होता है:

फ़ॉर्मूलाtext
userHash = HMAC_SHA256( identity_secret, payload )

payload = userId          // अगर userId सेट है
        = email           // अन्यथा, अगर email सेट है
        = (invalid)       // अगर दोनों खाली हैं, तो हस्ताक्षर करने को कुछ नहीं है
  • secret HMAC key है; पहचान-स्ट्रिंग message है — इसका उल्टा नहीं।
  • ठीक एक स्ट्रिंग पर हस्ताक्षर करें — कच्ची userId (या email), बिना किसी salt या JSON रैपर के।
  • अगर आप userId और email दोनों पास करते हैं, तो userId पर हस्ताक्षर करें (उसे प्राथमिकता मिलती है)।
  • आउटपुट hex है (SHA-256 के लिए 64 अक्षर), base64 नहीं।

Backend उदाहरण#

सिग्नेचर की गणना अपने backend पर करें और तैयार userHash ऐप को सौंपें।

Gogo
import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

// HMAC_SHA256(identity_secret, userId) लोअरकेस hex के रूप में।
func ComputeUserHash(identitySecret, userID string) string {
    mac := hmac.New(sha256.New, []byte(identitySecret))
    mac.Write([]byte(userID))
    return hex.EncodeToString(mac.Sum(nil))
}
Node.jsjavascript
const crypto = require("crypto");

// मोबाइल क्लाइंट पर Respondo.identify में पास करने के लिए userHash लौटाता है।
function computeUserHash(identitySecret, userId) {
  return crypto
    .createHmac("sha256", identitySecret)
    .update(userId, "utf8")
    .digest("hex");
}
Pythonpython
import hmac
import hashlib

# मोबाइल क्लाइंट पर Respondo.identify में पास करने के लिए userHash लौटाता है।
def compute_user_hash(identity_secret: str, user_id: str) -> str:
    return hmac.new(
        identity_secret.encode(),
        user_id.encode(),
        hashlib.sha256,
    ).hexdigest()
PHPphp
<?php
// मोबाइल क्लाइंट पर Respondo.identify में पास करने के लिए userHash लौटाता है।
function computeUserHash(string $identitySecret, string $userId): string {
    return hash_hmac('sha256', $userId, $identitySecret);
}

हैश Respondo तक कैसे पहुँचता है#

Respondo कोई identity एंडपॉइंट नहीं देता। कॉल करने के लिए कोई /identity रूट नहीं है और रजिस्टर करने के लिए कुछ भी नहीं है। userHash एक फ़ील्ड है जो उन्हीं रिक्वेस्ट्स के साथ जाता है जो SDK पहले से करता है।

दो हॉप, और उनमें से केवल पहला आपको बनाना है:

  1. आपका backend → आपका ऐप। हैश आप जैसे चाहें पहुँचाएँ। सबसे सस्ता विकल्प है उस लॉगिन/बूटस्ट्रैप रिस्पॉन्स में एक अतिरिक्त फ़ील्ड जो आप पहले से लौटाते हैं — कोई अतिरिक्त राउंड ट्रिप नहीं। आपके अपने backend पर एक समर्पित एंडपॉइंट (मान लीजिए POST /myapp/identity जो { userId, userHash } लौटाए) भी उतना ही अच्छा काम करता है। Respondo उस एंडपॉइंट को होस्ट नहीं करता — उसे आप लागू करते हैं।
  2. आपका ऐप → Respondo। यह आपके लिए संभाल लिया जाता है। एक बार आप identify कॉल कर देते हैं, तो SDK हर संबंधित रिक्वेस्ट के साथ हैश जोड़ देता है और backend हर बार उसे दोबारा सत्यापित करता है।
SDK इसे कहाँ रखता है (संदर्भ के लिए — इन्हें आप हाथ से नहीं भेजते)text
POST /api/v1/chat                      body   identity.userHash
GET  /api/v1/chat/resume               query  user_hash
GET  /api/v1/chat/history              query  user_hash
GET  /api/v1/chat/ws                   frames    user_hash (कनेक्ट के बाद subscribe/identify JSON फ़्रेम — handshake URL में नहीं)
GET  /api/v1/widget/tours              query  user_hash
GET  /api/v1/widget/checklists         query  user_hash
POST /api/v1/widget/push/register      body   user_hash

हैश हर रिक्वेस्ट पर दोबारा जाँचा जाता है, एक बार सेशन के बदले में नहीं दिया जाता — यही वजह है कि चुराई गई userId अकेले बेकार है।

अगर आपके backend पर डिलीवरी एंडपॉइंट अभी बना नहीं है, तो आपके अपने ऐप की रिक्वेस्ट 404 देती है, identify कभी कॉल नहीं होता, और चैट एनॉनिमस चलती है। यह अपेक्षित व्यवहार है, Respondo की त्रुटि नहीं — आपके अपने पाथ पर 404 आपकी तरफ़ का एक to-do है, टूटी हुई इंटीग्रेशन नहीं।

SDK को पहचान पास करना#

हस्ताक्षरित पहचान अपने backend से लाएँ, फिर userHash को किसी भी प्लेटफ़ॉर्म पर identify में पास करें:

Kotlinkotlin
Respondo.identify(
    RespondoIdentity(userId = "42", email = "user@example.com", userHash = hash),
)
Swiftswift
Respondo.identify(
    RespondoIdentity(userId: "42", email: "user@example.com", userHash: hash)
)
Dartdart
Respondo.identify(RespondoIdentity(
  userId: '42', email: 'user@example.com', userHash: hash,
));

अमान्य userHash का व्यवहार#

जब एजेंट पर सत्यापन चालू हो और सिग्नेचर गायब या ग़लत हो, तो backend एक चुपचाप एनॉनिमस में डाउनग्रेड करता है: चैट फिर भी चलती है, visitor_id बना रहता है, और बातचीत एनॉनिमस कॉन्टैक्ट से बँधी होती है — लेकिन प्रोफ़ाइल से कोई लिंक नहीं होता और कोई क्रॉस-डिवाइस इतिहास नहीं होता। अगर कोई यूज़र «पहचाना नहीं जाता», तो यह लगभग हमेशा सिग्नेचर होता है: जाँचें कि आपने userId पर हस्ताक्षर किया (email या JSON पर नहीं), सही identity_secret का उपयोग किया, और लोअरकेस hex उत्पन्न किया। अगर एजेंट का identity_secret खाली है, तो सत्यापन बंद है और userId / email जैसे हैं वैसे ही स्वीकार किए जाते हैं।

identity_secret को घुमाना प्रभावी रूप से एक हार्ड कटओवर है: पुराने secret से बना हर हैश तुरंत सत्यापित होना बंद कर देता है, इसलिए पहले से साइन-इन किए हुए यूज़र चुपचाप एनॉनिमस पर लौट आते हैं जब तक कि आपका backend उनका userHash नए secret के साथ दोबारा गणना करके फिर से न दे दे। secret को केवल तभी घुमाएँ जब आप हस्ताक्षर करने वाले पक्ष को उसी विंडो में अपडेट कर सकें।