אימות משתמשי קצה

פלטפורמת Contact Center AI משתמשת באימות משתמשי קצה כדי לזהות בצורה מאובטחת את האנשים שמשתמשים באפליקציית המארח שלכם. המנגנון הזה מבטיח שרק משתמשים מורשים יוכלו לגשת ל-API של פלטפורמת CCAI, ושהנתונים והשיחות שלהם בצ'אט יישארו קשורים בצורה מאובטחת לזהות הספציפית שלהם.

כדי לזהות משתמש קצה, אפליקציית המארח צריכה לספק מזהה ייחודי אוניברסלי (UUID) שמייצג את האדם הספציפי הזה.

איך האימות עובד ב-CCAI Platform

האימות ב-CCAI Platform מתבסס על לחיצת יד מאובטחת באמצעות אסימון אינטרנט מסוג JSON (JWT). ‫JWT הוא תקן פתוח שמשמש להעברת מידע בצורה מאובטחת כאובייקט JSON.

זהו תהליך האימות הרגיל:

  1. הבקשה: כשמשתמש קצה מתחיל להשתמש בשירות הלקוחות של CCAI Platform, ‏ CCAI Platform SDK מבקש JWT חתום מהאפליקציה המארחת.

  2. החתימה: אפליקציית המארח חותמת על ה-JWT באמצעות הסוד של החברה (company_secret) בפלטפורמת ה-CCAI המשותפת.

  3. הבורסה: אפליקציית המארח מעבירה את ה-JWT החתום בחזרה אל CCAI Platform SDK. לאחר מכן, ה-SDK שולח את ה-JWT הזה לשרת של פלטפורמת CCAI.

  4. האימות: השרת של CCAI Platform מאמת את החתימה. אם הרישיון תקף, פלטפורמת CCAI מנפיקה אסימון הרשאה, ומעניקה למשתמש גישה ל-API ומשייכת אותו לחשבון שלו (או יוצרת חשבון חדש אם הוא לא קיים).

אם אפליקציית המארח לא מספקת מזהה במטען הייעודי (payload) של JWT, פלטפורמת CCAI תיצור חשבון אורח אנונימי עבור המשתמש.

דרישות מוקדמות

לפני שמטמיעים אימות, צריך את רכיבי האימות הייחודיים של ה-SDK. הם משמשים לזיהוי מאובטח של החברה שלכם ב-API של פלטפורמת CCAI.

  1. נכנסים ל-CCAI Platform באמצעות חשבון אדמין.

  2. עוברים אל הגדרות > הגדרות למפתחים > פרטי כניסה ל-API.

  3. מאתרים את שם מפתח ה-SDK ‏ (sdk_key_name), מפתח ה-SDK ‏ (sdk_key) והסוד של החברה (company_secret).

חשוב לשמור על פרטי הכניסה האלה. שתפו אותם רק עם מערכות מורשות ומפתחים מורשים.

מדריך הטמעה למפתחים

בקטע הבא מוסבר איך מפתחים צריכים ליצור את מטען ה-JWT ולהפעיל את CCAI Platform SDK בפלטפורמות שונות.

דרישות לגבי ה-payload של JWT

כדי להעביר את פרטי משתמש הקצה אל CCAI Platform, אפליקציית המארח צריכה ליצור מטען ייעודי (payload) של JWT. שיטת הקריאה החוזרת מספקת מטען ייעודי (payload) שמוגדר כברירת מחדל (שיכול לכלול אסימון push ושם שמוגדר כברירת מחדל), אבל אפשר להוסיף פרטים ספציפיים של משתמשים באמצעות המפתחות השמורים הבאים:

  • ‫identifier (אופציונלי, אבל מומלץ מאוד להשתמש במזהה ייחודי אוניברסלי)

  • ‫name (אופציונלי)

  • ‫email (אופציונלי)

  • ‫phone (אופציונלי, צריך להשתמש בפורמט E.164)

  • iss (אופציונלי, שם החברה)

  • iat (חובה, מונפק בחותמת הזמן)

  • ‫exp (חובה, חותמת זמן לציון תוקף)

חתימה בצד השרת (מומלץ)

.

דוגמה ל-API בשרת (Ruby on Rails)

בדוגמה הזו מוצג אופן החתימה על מטען הייעודי (payload) בצד השרת באמצעות Ruby on Rails framework עם JWT gem.

הקוד מגדיר נקודת קצה ל-API ‏(/api/ujet/sign) באמצעות jwt gem כדי לקודד את מטען הייעודי (payload) באמצעות סוד של החברה ולהחזיר את הטוקן המקודד ללקוח.

נניח שכתובת ה-URL הבסיסית של אפליקציית המארח היא https://company.com/api/. כדי לחתום על מטען הייעודי (payload) עבור CCAI Platform, אפשר להוסיף עוד נקודת קצה ל-API בכתובת https://company.com/api/ujet/sign.

הקוד מוסיף נתיב חדש לקובץ הנתיבים של האפליקציה כדי לטפל בבקשות POST לכתובת ה-URL‏ /api/ujet/sign.

בקובץ ujet_controller.rb מוגדרת המחלקה UjetController, שיש לה נקודת קצה אחת, sign, שמשמשת לחתימה על מטען ייעודי (payload) עבור CCAI Platform.

בקוד, COMPANY_SECRET מוגדר כסוד שמשמש לחתימה על מטען הייעודי (payload). המטען הייעודי חולץ מגוף הבקשה ואז מתווספים אליו ערכים שונים, למשל: מזהה ייחודי, שם משתמש, אימייל, טלפון.

ה-method‏ JWT.encode משמשת לקידוד המטען הייעודי (payload) וה-ujet_secret לטוקן אינטרנט מסוג JSON‏ (JWT), שמוחזר בתגובה כאובייקט JSON עם מפתח הטוקן.

# routes.rb
post 'ujet/sign' => "ujet#sign"

# ujet_controller.rb
class UjetController
  def sign
    # In production, securely store and call your secret (e.g., via environment variables)
    ujet_secret = "COMPANY_SECRET"

    payload = body["payload"]
    payload["identifier"] = "UNIQUE-IDENTIFIER"
    payload["name"] = "user name"
    payload["email"] = "test@email.com"
    payload["phone"] = ""                     # E.164 format
    payload["iss"] = "YOUR_COMPANY_NAME"
    payload["iat"] = Time.now.to_i
    payload["exp"] = Time.now.to_i + 10.minutes # Valid for 10 minutes

    token = JWT.encode(payload, ujet_secret)

    render json: {token: token}
  end
end

אתחול בצד הלקוח

כדי להפעיל את CCAI Platform Mobile SDK, פועלים לפי ההנחיות הבאות.

חתימה מ-iOS SDK

בדוגמה הזו לחתימה על מטען ייעודי (payload) מ-iOS SDK, מתבצעת בקשת POST לשרת בכתובת ה-URL https://your.company.com/api/ujet/sign עם המטען הייעודי כגוף הבקשה.

השרת אמור להחזיר אסימון חתום בתגובה, שמועבר לאחר מכן לקריאה החוזרת של ההצלחה בצורה של מפתח token באובייקט JSON.

אם מתרחשת שגיאה במהלך הבקשה, היא מועברת לקריאה החוזרת של הכשל.

-   (void)signPayload:(NSDictionary *)payload payloadType:(UjetPayloadType)payloadType success:(void (^)(NSString *))success failure:(void (^)(NSError *))failure
{
  if (payloadType == UjetPayloadAuthToken) {
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

    NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] init];
    mutableRequest.URL = [NSURL URLWithString:@"https://your.company.com/api/ujet/sign"];
    mutableRequest.HTTPMethod = @"POST";
    NSError *error;
    NSDictionary *data = @{@"payload": payload};
    mutableRequest.HTTPBody = [NSJSONSerialization dataWithJSONObject:data options:0 error:&error];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:mutableRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if(error) {
            failure(error);
        }
        else {
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            success(json[@"token"]);
        }
    }];

    [task resume];
  }
}

חתימה מ-Android SDK

הנה דוגמה לחתימה על מטען ייעודי (payload) מ-Android SDK.

בדוגמה הזו נעשה שימוש ב-Retrofit, צד לקוח HTTP ל-Android, כדי לבקש את מטען הייעודי (payload) החתום מהשרת. הפונקציה מקבלת מטען ייעודי (payload), סוג מטען ייעודי וקריאה חוזרת של אסימון כקלט.

אם סוג ה-payload הוא UjetPayloadType.AuthToken, נוצר מופע Retrofit, נעשה בו שימוש כדי לשלוח בקשה לנקודת הקצה של https://company.com/api API כדי לחתום על ה-payload, והאסימון החתום מוחזר בשיטה onToken של מופע tokenCallback.

אם הניסיון ייכשל, תוצג הודעה קצרה "Authentication failed".

public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, final UjetTokenCallback tokenCallback) {
    if (ujetPayloadType == UjetPayloadType.AuthToken) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://company.com/api/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        AuthService authService = retrofit.create(AuthService.class);
        Call<AuthToken> authenticate = authService.authenticate(new AuthRequest(payload));
        authenticate.enqueue(new Callback<AuthToken>() {
            @Override
            public void onResponse(Call<AuthToken> call, Response<AuthToken> response) {
                if (response.isSuccessful()) {
                    AuthToken authToken = response.body();
                    tokenCallback.onToken(authToken.getToken());
                } else {
                    Toast.makeText(ExampleApplication.this, "Authentication failed", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<AuthToken> call, Throwable t) {
                Toast.makeText(ExampleApplication.this, "Authentication failed", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

חתימה מ-Web SDK

בדוגמה הבאה אפשר לראות איך חותמים על המטען הייעודי (payload) ב-Web SDK על ידי שליחת בקשת API לשרת עם המטען הייעודי.

השרת צריך להיות מוגדר לטיפול בבקשת ה-API ולחתימה על מטען הייעודי (payload) באמצעות שיטה מאובטחת. התוצאה מוחזרת לדף האינטרנט, שמעביר את האסימון החתום בחזרה ל-CCAI Platform באמצעות פונקציית הקריאה החוזרת.

$(function() {
  UJET.initialize({
    // ... other parameters
    handlers: {
      authentication(callback) {
        $.ajax({
          type: 'POST',
          url: 'https://company.com/api/ujet/sign',
          data: JSON.stringify({
            payload: {
              identifier: 'UNIQUE-Identifier',
              name: 'Test user'
            }
          }),
          success: function(result) {
            callback({
              token: result.token,
              user: {
                identifier: 'UNIQUE-IDENTIFIER',
                name: 'Test user'
              }
            });
          }
        });
      }
    }
  }).then(function() {
    // successfully initialized
  }).catch(function(error) {
    // Handle initialization error
  });
});

אימות באמצע הסשן ואתחול מחדש של ה-SDK

במקרים מסוימים, משתמש קצה עשוי להתחיל סשן צ'אט כאורח (לא מאומת) ולאמת את הזהות שלו באמצע הסשן (למשל, באמצעות עוזר וירטואלי או מסך כניסה באמצע התהליך). כדי לוודא שהעדכון של הסשן הפעיל מתבצע בצורה מאובטחת ושהוא משויך למשתמש שאומת לאחרונה, פועלים לפי השלבים הבאים:

שלבים לאימות באמצע הסשן

  1. אתחול ה-SDK עם מזהה זמני: כשהמשתמש לא מאומת, צריך לאתחל את CCAI Platform SDK באמצעות מזהה אקראי או מזהה אורח.

  2. הפניית המשתמש לאימות: צריך להפנות את המשתמש לתהליך האימות, למשל לעוזר וירטואלי (VA) של CCAI Platform או למסך הכניסה המובנה של האפליקציה.

  3. עדכון משתמש הקצה באמצעות API: אחרי שהמשתמש עובר אימות בהצלחה (ובזמן שהוא עדיין בנציג הווירטואלי או בתהליך האימות), ה-backend צריך להפעיל את CCAI Platform Apps API כדי לעדכן את סשן הצ'אט של משתמש הקצה עם המזהה האמיתי שלו.

  4. מפעילים מחדש את ה-SDK עם JWT חדש: אחרי עדכון מוצלח של הקצה העורפי, יוצרים JWT חדש בשביל המשתמש המאומת. מאתחלים מחדש את CCAI Platform SDK על ידי קריאה חוזרת לשיטת האתחול עם ה-JWT החדש.

  5. העברת הסשן לטיפול ברמה גבוהה יותר (אם משתמשים ב-VA): אם המשתמש ביצע אימות באמצעות סוכן וירטואלי, הסוכן הווירטואלי צריך להעביר את הצרכן לתור היעד הסופי שלו.

דוגמה (Web SDK)

כדי לאתחל מחדש, קוראים שוב לפונקציה UJET.initialize. הפעולה הזו תפעיל את ה-handler של האימות כדי לאחזר את הטוקן החדש.

// Call this after successful authentication and the CCAI Platform Apps API update
UJET.initialize({
  // ...include your existing parameters
  handlers: {
    authentication(callback) {
      // Fetch the new JWT for the newly authenticated user
      $.ajax({
        type: 'POST',
        url: 'https://your.company.com/api/ujet/sign',
        data: JSON.stringify({
          payload: {
            identifier: 'AUTHENTICATED-USER-UUID',
            name: 'Authenticated User Name'
          }
        }),
        success: function(result) {
          callback({
            token: result.token,
            user: {
              identifier: 'AUTHENTICATED-USER-UUID',
              name: 'Authenticated User Name'
            }
          });
        }
      });
    }
  }
}).then(function() {
  // SDK successfully reinitialized with the authenticated user
}).catch(function(error) {
  // Handle reinitialization errors
});

למה זה נחוץ?

  • כך מובטח שכל הפעולות, הניתוב וההיסטוריה הבאים ישויכו בצורה מאובטחת למשתמש המאומת, ולא לסשן של אורח אנונימי.

  • כך נמנעת דליפת נתונים ונשמרים רשומות מדויקות של משתמשים ושל נתונים במערכת ה-CRM.

טבלת סיכום

תרחיש נדרשת פעולה
המשתמש מתחיל כשהוא מאומת מאתחלים את ה-SDK עם ה-UUID וה-JWT האמיתיים של המשתמש.
המשתמש מתחיל ללא אימות מפעילים את ה-SDK עם מזהה אקראי או מזהה של משתמש לא רשום.
המשתמש מאומת באמצע הסשן מעדכנים את CCAI Platform באמצעות ה-API, יוצרים JWT חדש ומפעילים מחדש את ה-SDK.