Mobil SDK açarları və istifadəçinin tanıdılması (user_hash)

Son yeniləmə: 9 oktyabr 2026 · 9 dəq oxunur

Giriş olmadan Messenger anonim ziyarətçi üçün açılır. İstifadəçi tətbiqinizə daxil olanda Clomni-yə onun kim olduğunu bildirin: onda operatorlar adını, e-poçtunu və atributlarını görür, istifadəçi hər cihazda eyni söhbətləri görür, ziyarətçi ikən yazdıqları da ona keçir.

Addımlar

  1. 1

    Açarlar və onların yeri

    • App ID (app_…): tətbiqdə.
    • Android API açarı (android_…): Android tətbiqində.
    • iOS API açarı (ios_…): iOS tətbiqində.
    • Identity Secret (uzun təsadüfi sətir): yalnız serverinizdə. Nə koda, nə BuildConfig-ə, nə Info.plist-ə, nə tətbiqlə gedən .env-ə, nə Unity asset-lərinə.

    API açarı bir platformaya bağlıdır: iOS açarı Android-də işləmir. React Native, Flutter və Unity tətbiqləri hansı platformada işləyirlərsə, onun açarını verir. Açarlar Parametrlər › İş sahəsi parametrləri › Gələn qutular › kanalınız › ayarlar sütunu › Quraşdırma bölməsindədir, Identity Secret isə Təhlükəsizlik bölməsində.

  2. 2

    Necə işləyir

    1. İstifadəçi tətbiqinizə daxil olur.
    2. Serveriniz Identity Secret ilə istifadəçinin ID-sindən user_hash hesablayır və onu tətbiqə qaytarır, məsələn login cavabında.
    3. Tətbiq istifadəçi və hash ilə loginUser çağırır.

    Hash serverinizin bu ID-yə zəmanət verdiyini sübut edir. Onsuz istifadəçinin ID-sini bilən hər kəs öz telefonundan onun söhbətlərini aça bilərdi.

  3. 3

    Düstur

    user_hash = hex(HMAC-SHA256(identity_secret, user_id))
    • Nəticə 64 simvolluq kiçik hərfli hex-dir.
    • user_id sətirdir və tətbiqin loginUser-ə verdiyi ilə hərfbəhərf eynidir. 12345 və "12345" eynidir, "012345" isə başqadır.
    • Tətbiq istifadəçini userId olmadan daxil edirsə, hash e-poçtdan alınır: kənar boşluqlar silinmiş, kiçik hərflərlə.
    • Dəyişməyən ID işlədin. E-poçt dəyişə bilirsə, onu ID kimi işlətməyin.

    Kodunuzu yoxlamaq üçün: secret test_secret və user_id 12345 ilə hash b01354f5d4c60c56ca76a26c064b9629b0d2a73e169b63b6514b974a9714cf24 olmalıdır.

  4. 4

    Server kodu

    Hər nümunə secret-i CLOMNI_IDENTITY_SECRET mühit dəyişənindən oxuyur.

    // Node.js
    const crypto = require('crypto');
    
    function clomniUserHash(userId) {
      return crypto
        .createHmac('sha256', process.env.CLOMNI_IDENTITY_SECRET)
        .update(String(userId))
        .digest('hex');
    }
    
    // Return the hash with your own login response (Express).
    app.post('/api/login', async (req, res) => {
      const user = await logIn(req.body.email, req.body.password); // your own login
      res.json({ user, clomniUserHash: clomniUserHash(user.id) });
    });
    <?php
    // PHP
    function clomni_user_hash(string $userId): string
    {
        return hash_hmac('sha256', $userId, getenv('CLOMNI_IDENTITY_SECRET'));
    }
    # Python
    import hashlib
    import hmac
    import os
    
    def clomni_user_hash(user_id) -> str:
        secret = os.environ["CLOMNI_IDENTITY_SECRET"].encode()
        return hmac.new(secret, str(user_id).encode(), hashlib.sha256).hexdigest()
    # Ruby
    require 'openssl'
    
    def clomni_user_hash(user_id)
      OpenSSL::HMAC.hexdigest('SHA256', ENV.fetch('CLOMNI_IDENTITY_SECRET'), user_id.to_s)
    end
    // Java
    import java.nio.charset.StandardCharsets;
    import java.security.GeneralSecurityException;
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    public final class ClomniUserHash {
        private ClomniUserHash() {}
    
        public static String of(String userId) throws GeneralSecurityException {
            String secret = System.getenv("CLOMNI_IDENTITY_SECRET");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] digest = mac.doFinal(userId.getBytes(StandardCharsets.UTF_8));
            StringBuilder hex = new StringBuilder(digest.length * 2);
            for (byte b : digest) {
                hex.append(String.format("%02x", b));
            }
            return hex.toString();
        }
    }
    // C# (.NET 5 or newer)
    using System;
    using System.Security.Cryptography;
    using System.Text;
    
    public static class ClomniUserHash
    {
        public static string Of(string userId)
        {
            var secret = Environment.GetEnvironmentVariable("CLOMNI_IDENTITY_SECRET")!;
            using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
            var digest = hmac.ComputeHash(Encoding.UTF8.GetBytes(userId));
            return Convert.ToHexString(digest).ToLowerInvariant();
        }
    }
    // Go
    package clomni
    
    import (
    	"crypto/hmac"
    	"crypto/sha256"
    	"encoding/hex"
    	"os"
    )
    
    // UserHash is the user_hash Clomni expects for userID.
    func UserHash(userID string) string {
    	mac := hmac.New(sha256.New, []byte(os.Getenv("CLOMNI_IDENTITY_SECRET")))
    	mac.Write([]byte(userID))
    	return hex.EncodeToString(mac.Sum(nil))
    }

    C#-da Convert.ToHexString böyük hərflərlə qaytarır, ona görə ToLowerInvariant lazımdır.

  5. 5

    Tətbiqdə giriş, dəyişiklik və çıxış

    loginUser-i öz login-iniz uğurla bitəndən sonra, serverdən gələn hash ilə çağırın. userId-dən başqa sahələr istəyə bağlıdır, phone da var.

    // Android
    Clomni.loginUser(ClomniUser(userId = "12345", email = "[email protected]", name = "Aysel"), userHash = hashFromYourServer)
    Clomni.updateUser(language = "az", customAttributes = mapOf("plan" to "premium"))
    Clomni.logout()
    // iOS
    Clomni.loginUser(ClomniUser(userId: "12345", email: "[email protected]", name: "Aysel"), userHash: hashFromYourServer)
    Clomni.updateUser(language: "az", customAttributes: ["plan": "premium"])
    Clomni.logout()
    // React Native
    Clomni.loginUser({ userId: '12345', email: '[email protected]', name: 'Aysel' }, hashFromYourServer);
    Clomni.updateUser({ language: 'az', customAttributes: { plan: 'premium' } });
    Clomni.logout();
    // Flutter
    await Clomni.loginUser(
      const ClomniUser(userId: '12345', email: '[email protected]', name: 'Aysel'),
      userHash: hashFromYourServer,
    );
    await Clomni.updateUser(language: 'az', customAttributes: {'plan': 'premium'});
    await Clomni.logout();
    // Unity
    Clomni.LoginUser(new ClomniUser { UserId = "12345", Email = "[email protected]", Name = "Aysel" }, hashFromYourServer);
    Clomni.UpdateUser(language: "az", customAttributes: new Dictionary<string, object> { ["plan"] = "premium" });
    Clomni.Logout();
    • updateUser yalnız verilən sahələri dəyişir: ad, dil (az, en, ru), fərdi atributlar. Atributlar operatorun söhbətin yan panelində gördüyü atributlarla birləşdirilir.
    • logout-u tətbiqin öz çıxışı ilə birlikdə çağırın. O, Clomni sessiyasını bağlayır və Messenger-in cihazdakı məlumatını silir. Onsuz bu telefona sonra daxil olan şəxs əvvəlkinin söhbətlərini görür.

    Tətbiq hər açılanda, istifadəçi daxil olubsa, loginUser-i yenidən çağırın, istifadəçi təzə daxil olmuş kimi. Eyni istifadəçi üçün SDK saxlanmış sessiyanı işlədir.

  6. 6

    Rejimlər

    Rejim ayarlar sütunu › Təhlükəsizlik › «Rejim» sahəsindədir.

    • «Söndürülüb»: hash yoxlanmır, istənilən hash qəbul olunur. Tətbiqə başqasının user_id-sini verən onun söhbətlərini aça bilər. Yalnız sınaq üçündür: istehsalda heç vaxt işlətməyin.
    • «Tövsiyə olunan» (standart): göndərilən hash düzgün olmalıdır, səhv hash girişi rədd edir. Hash olmadan istifadəçi qəbul olunur, amma təsdiqlənmir. İstifadəçi bir dəfə təsdiqlənmiş hash ilə daxil olandan sonra ondan hər dəfə hash istənilir.
    • «Məcburi»: düzgün hash olmadan giriş yoxdur, server 403 identity_verification_failed qaytarır. Yalnız tətbiqdən ilk təsdiqlənmiş girişdən sonra seçmək olar. Hash göndərməyən köhnə tətbiq versiyaları qoşula bilmir.

    Yaxşı ardıcıllıq: tətbiqi user_hash ilə «Tövsiyə olunan» rejimdə buraxın, «Ümumi baxış»da hash xəbərdarlığı qalmayana qədər izləyin, sonra «Məcburi»yə keçin.

  7. 7

    Hash-i yoxlayın

    Ayarlar sütunu › Təhlükəsizlik › «Hash-i yoxla»: user_id-ni və serverinizin hazırladığı user_hash-i yazın, «Yoxla» basın. Panel hash-in cari secret ilə, köhnə secret ilə hazırlandığını və ya heç birinə uyğun gəlmədiyini deyir. Düzgün cavab: «Düzdür. Hash cari secret ilə hazırlanıb.» Hash 64 simvollu hex deyilsə, panel bunu ayrıca deyir.

  8. 8

    Secret və açarın dəyişdirilməsi

    • Təhlükəsizlik › «Yeni secret yarat»: yeni secret bir dəfə göstərilir, köhnəsi daha 7 gün işləyir (panel tarixi yazır). Bu müddətdə serverinizi yeni secret-ə keçirin.
    • Quraşdırma › «Yeni açar»: yeni API açarı, köhnəsi daha 7 gün işləyir. Yeni açarı yalnız köhnəsi sızanda, ya da istifadəçilərin çoxunun quraşdıracağı buraxılışla birlikdə yaradın.
    • Quraşdırma › «Ləğv et»: açar dərhal dayanır.
  9. 9

    Tam təlimat

Sənəd