최종 사용자 인증

Contact Center AI Platform은 최종 사용자 인증을 사용하여 호스트 앱을 사용하는 사용자를 안전하게 식별합니다. 이 메커니즘을 통해 승인된 사용자만 CCAI Platform API에 액세스할 수 있으며 채팅 세션과 데이터가 특정 ID에 안전하게 연결됩니다.

최종 사용자를 식별하려면 호스트 앱이 특정 사용자를 나타내는 범용 고유 식별자 (UUID)를 제공해야 합니다.

CCAI Platform의 인증 작동 방식

CCAI Platform의 인증은 JSON 웹 토큰 (JWT)을 사용하는 보안 핸드셰이크를 기반으로 합니다. JWT는 정보를 JSON 객체로 안전하게 전송하는 데 사용되는 공개 표준입니다.

표준 인증 흐름은 다음과 같습니다.

  1. 요청: 최종 사용자가 CCAI Platform 고객 서비스를 사용하기 시작하면 CCAI Platform SDK가 호스트 앱에서 서명된 JWT를 요청합니다.

  2. 서명: 호스트 앱은 공유 CCAI 플랫폼 회사 비밀 (company_secret)을 사용하여 JWT에 서명합니다.

  3. 교환: 호스트 앱이 서명된 JWT를 CCAI Platform SDK에 다시 전달합니다. 그러면 SDK가 이 JWT를 CCAI Platform 서버로 전송합니다.

  4. 확인: CCAI Platform 서버가 서명을 확인합니다. 유효한 경우 CCAI 플랫폼에서 인증 토큰을 발급하여 사용자에게 API 액세스 권한을 부여하고 사용자를 계정과 연결합니다 (또는 계정이 없는 경우 새 계정을 만듭니다).

호스트 앱이 JWT 페이로드에 식별자를 제공하지 않으면 CCAI 플랫폼에서 사용자를 위한 익명의 게스트 계정을 만듭니다.

기본 요건

인증을 구현하기 전에 고유한 SDK 인증 요소가 필요합니다. 이러한 키는 CCAI Platform API에서 회사를 안전하게 식별합니다.

  1. 관리자 계정으로 CCAI Platform에 로그인합니다.

  2. 설정 > 개발자 설정 > API 사용자 인증 정보로 이동합니다.

  3. SDK 키 이름 (sdk_key_name), SDK 키 (sdk_key), 회사 비밀번호 (company_secret)를 찾습니다.

이 사용자 인증 정보를 안전하게 보관하세요. 승인된 시스템 및 개발자와만 공유하세요.

개발자 구현 가이드

다음 섹션에서는 개발자가 다양한 플랫폼에서 JWT 페이로드를 구성하고 CCAI Platform SDK를 초기화하는 방법을 설명합니다.

JWT 페이로드 요구사항

최종 사용자의 정보를 CCAI Platform에 전달하려면 호스트 앱이 JWT 페이로드를 구성해야 합니다. 콜백 메서드는 기본 페이로드 (푸시 토큰과 기본 이름을 포함할 수 있음)를 제공하지만 다음 예약된 키를 사용하여 특정 사용자 세부정보를 추가할 수 있습니다.

  • identifier (선택사항이지만 적극 권장되는 UUID)

  • name(선택사항)

  • email(선택사항)

  • phone (선택사항, E.164 형식을 사용해야 함)

  • iss (선택사항, 회사 이름)

  • iat (필수, 발급 시 타임스탬프)

  • exp (필수, 만료 타임스탬프)

서버 측 서명 (권장)

서버의 API 예 (Ruby on Rails)

이 예시에서는 JWT gem과 함께 Ruby on Rails 프레임워크를 사용하여 서버 측에서 페이로드를 서명하는 방법을 보여줍니다.

이 코드는 jwt gem을 사용하여 API 엔드포인트 (/api/ujet/sign)를 설정하여 회사 보안 비밀로 페이로드를 인코딩하고 인코딩된 토큰을 클라이언트에 반환합니다.

호스트 애플리케이션의 기본 URL이 https://company.com/api/라고 가정해 보겠습니다. CCAI Platform의 페이로드를 서명하려면 https://company.com/api/ujet/sign에 다른 API 엔드포인트를 추가하면 됩니다.

이 코드는 /api/ujet/sign URL에 대한 POST 요청을 처리하기 위해 애플리케이션의 경로 파일에 새 경로를 추가합니다.

ujet_controller.rb 파일은 CCAI 플랫폼의 페이로드를 서명하는 데 사용되는 단일 엔드포인트 sign이 있는 UjetController 클래스를 정의합니다.

코드에서 COMPANY_SECRET는 페이로드에 서명하는 데 사용되는 보안 비밀로 정의됩니다. 페이로드는 요청 본문에서 추출된 후 UNIQUE-IDENTIFIER, 사용자 이름, 이메일, 전화번호와 같은 다양한 값이 추가됩니다.

JWT.encode 메서드는 페이로드와 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 모바일 SDK를 초기화하세요.

iOS SDK에서 서명

iOS SDK에서 페이로드를 서명하는 이 예시에서는 페이로드를 요청 본문으로 사용하여 https://your.company.com/api/ujet/sign URL의 서버에 POST 요청을 수행합니다.

서버는 서명된 토큰을 응답으로 반환해야 하며, 이 토큰은 JSON 객체의 'token' 키 형식으로 성공 콜백에 전달됩니다.

요청 중에 오류가 발생하면 실패 콜백에 전달됩니다.

-   (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에서 서명

다음은 Android SDK에서 페이로드에 서명하는 예입니다.

이 예에서는 Android용 HTTP 클라이언트인 Retrofit을 사용하여 서버에서 서명된 페이로드를 요청합니다. 이 함수는 페이로드, 페이로드 유형, 토큰 콜백을 입력으로 사용합니다.

페이로드 유형이 UjetPayloadType.AuthToken인 경우 Retrofit 인스턴스를 만들고 이를 사용하여 https://company.com/api API 엔드포인트에 요청을 보내 페이로드에 서명하고 tokenCallback 인스턴스의 onToken 메서드에서 서명된 토큰을 반환합니다.

실패하면 토스트 메시지 "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();
            }
        });
    }
}

웹 SDK에서 서명

다음 예에서는 페이로드를 사용하여 서버에 API 요청을 전송하여 Web SDK에서 페이로드에 서명하는 방법을 보여줍니다.

서버는 API 요청을 처리하고 보안 방법을 사용하여 페이로드에 서명하도록 설정해야 합니다. 그러면 결과가 웹페이지로 반환되고, 웹페이지는 콜백 함수를 사용하여 서명된 토큰을 CCAI 플랫폼으로 다시 전달합니다.

$(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. 사용자에게 인증 안내: CCAI Platform 가상 어시스턴트 (VA) 또는 앱의 내장 로그인 화면과 같은 인증 흐름으로 사용자를 안내합니다.

  3. API를 통해 최종 사용자 업데이트: 사용자가 인증을 완료한 후(가상 에이전트 또는 인증 플로우에 있는 동안) 백엔드에서 CCAI Platform Apps API를 호출하여 최종 사용자의 채팅 세션을 실제 식별자로 업데이트해야 합니다.

  4. 새 JWT로 SDK 재초기화: 백엔드 업데이트가 완료되면 인증된 사용자를 위한 새 JWT를 생성합니다. 이 새 JWT로 초기화 메서드를 다시 호출하여 CCAI Platform SDK를 다시 초기화합니다.

  5. 세션 에스컬레이션 (VA 사용 시): 사용자가 가상 어시스턴트를 사용하여 인증한 경우 가상 상담사는 이제 소비자를 최종 목적지 대기열로 에스컬레이션해야 합니다.

예 (웹 SDK)

다시 초기화하려면 UJET.initialize 함수를 다시 호출합니다. 그러면 인증 핸들러가 새 토큰을 가져오도록 트리거됩니다.

// 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 및 사용자 기록을 유지합니다.

요약 표

시나리오 조치 필요
사용자가 인증된 상태로 시작 사용자의 실제 UUID와 JWT로 SDK를 초기화합니다.
사용자가 인증되지 않은 상태로 시작 게스트/임의 식별자로 SDK를 초기화합니다.
사용자가 세션 중에 인증 API로 CCAI Platform을 업데이트하고, 새 JWT를 생성하고, SDK를 다시 초기화합니다.