SDK エンドユーザー認証

Contact Center AI Platform(CCAI Platform)のエンドユーザー認証プロセスは、ホスト アプリケーションを使用しているユーザーを特定するための安全な方法です。エンドユーザーは、ホストアプリから提供される Universally Unique Identifier(UUID)によって識別されます。CCAI Platform SDK は、認証が必要なときに、共有シークレット キー(company_secret)で署名され、ホスト アプリケーションによって提供される JSON ウェブ トークン(JWT)をリクエストします。ホストアプリが JWT を提供すると、CCAI Platform SDK は認証プロセスを開始して認証トークンを取得します。

エンドユーザー

このコンテキストのエンドユーザーは、ホスト アプリケーションのユーザーを指します。

エンドユーザーを識別するために、CCAI Platform はホストアプリから提供された識別子を使用します。この識別子は、各ユーザーに固有の UUID(Universally Unique Identifier)である必要があります。

UUID を使用すると、エンドユーザーのメールアドレスが変更されても、エンドユーザーを正確に識別し、他のユーザーと区別できます。

CCAI プラットフォームで認証する

JSON Web Token(JWT)は、CCAI Platform にリクエストを行うユーザーまたはアプリケーションを安全に識別するために使用されます。ホスト アプリケーションは、コールバックを介して JWT を CCAI Platform SDK に提供します。CCAI Platform SDK は、認証が必要なときに、共有 SDK キー(sdk_key)を使用して JWT を提供するようホスト アプリケーションに要求します。

ホスト アプリケーションがコールバックを介して CCAI Platform SDK に JWT を提供した場合、CCAI Platform SDK は CCAI Platform に対する認証を開始し、認証トークンを取得します。

JWT のペイロードには、ユーザーの ID、メールアドレス、名前、電話番号などの情報が含まれる場合があります。 Google Cloud では、電話番号に E.164 形式を使用することをおすすめします。この情報は、ユーザーの新しいアカウントを作成するか、CCAI Platform の既存のアカウントにユーザーを関連付けるために使用されます。

ホスト アプリケーションが JWT ペイロードで識別子を提供する場合、CCAI Platform はその識別子を使用してユーザーを作成するか、アカウントに関連付けます。ID が指定されていない場合、CCAI Platform はユーザーの匿名アカウントを作成します。

CCAI Platform への JWT 署名の詳細については、JWT 署名セクションをご覧ください。

SDK キーを管理する

sdk_key_name フィールドと sdk_key フィールドは、重要な認証要素です。これらは会社を一意に識別し、CCAI Platform API に安全にアクセスするために使用されます。

SDK キーを管理する手順は次のとおりです。

  1. 管理者ロールを持つユーザーとして CCAI Platform ポータルにログインします。

  2. CCAI Platform ポータルで、[設定 > デベロッパー設定] をクリックします。[設定] メニューが表示されない場合は、 [メニュー] をクリックします。

  3. [Company Key & Secret Code] ペインに移動して、認証トークンの生成に使用される SDK キーを管理します。

これらのコードは安全に保管し、CCAI Platform API へのアクセスを必要とする承認済みの個人またはシステムとのみ共有する必要があります。これらのコードに不正にアクセスされると、データとシステムのセキュリティが侵害される可能性があります。

認証ワークフロー

認証ワークフローは次のとおりです。

  1. CCAI Platform は、ホストアプリに SDK キー名 (sdk_key_name) と SDK キー(sdk_key)を提供します。これらは、[設定] > [デベロッパー設定] > [SDK キー] で確認できます。

  2. エンドユーザーが CCAI Platform カスタマー サービスの使用を開始すると、CCAI Platform SDK はホスト アプリケーションに JWT 署名をリクエストします。

  3. CCAI Platform は、署名付き JWT を検証し、エンドユーザー認証トークンを発行します。このプロセスにより、ホスト アプリケーションと CCAI Platform カスタマー サービス間の安全でシームレスな認証が保証されます。

JWT 署名

ホスト アプリケーションは、プラットフォームごとにコールバック メソッドを実装する必要があります。以降のセクションでは、各プラットフォームの手順を説明します。

エンドユーザーの情報を処理するには、ホストアプリで JWT ペイロードを入力する必要があります。デフォルトのペイロードはコールバック メソッドを通じて提供され、プッシュ トークンやデフォルト名などの値がすでに含まれている場合があります。

ホストアプリは、次のような予約済みのキー名を使用して、ユーザーに関する詳細情報を追加できます。

  • identifier(省略可)

  • name(省略可)

  • メールアドレス(省略可)

  • 電話番号(省略可、E.164 形式)

たとえば、iOS SDK の場合、テスト目的でメソッドの実装を次のようにすることができます(JWT を使用)。

- (void)signPayload:(NSDictionry *)payload payloadType:(UjetPayloadType)payloadType success:(void (^)(NSString *))success ailure:(void (^)(NSError *))failure
{
  if (payloadType == UjetPayloadAuthToken) {
    @try {
        NSString *companySecre = @"COMPANY_SECRET";
        NSMutableDictionary *pyloadData = [payload mutableCopy];
        payloadData[@"identifir"] = @"UNIQUE-IDENTIFIER"; // optional
        payloadData[@"name"] =@"user name";            // optional
        payloadData[@"email"]  @"test@email.com";      // optional
        payloadData[@"phone"]  @"";                    // optional, E.164 format 
        payloadData[@"iss"] = "YOUR_COMPANY_NAME";     // optional
        payloadData[@"iat"] = NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]; // required
        payloadData[@"exp"] = NSNumber numberWithDouble:([[NSDate date] timeIntervalSince1970]+ 600)]; // required

        id<JWTAlgorithm> algorthm = [JWTAlgorithmFactory algorithmByName:@"HS256"];
        NSString *signedToken  [JWTBuilder encodePayload:payload].secret(companySecret).algorithm(algorithm).ecode;
        success(signedToken);
    }
    @catch (NSError *error) {
        failure(error);
    }
  }
}

本番環境の例

Google Cloud では、セキュリティを強化するために、サーバーサイドでペイロードに署名することをおすすめします。これにより、会社のシークレットがクライアント側で公開されることはなく、リスクがあると判断された場合はいつでも取り消すことができます。このアプローチは、クライアント側でペイロードに署名するよりもセキュリティが強化されます。

次のコード スニペットは、JWT gem を使用した Ruby on Rails フレームワークによるサーバーサイドでのペイロードの署名と、iOS SDK、Android SDK、Web SDK を使用したクライアントサイドでのペイロードの署名の例を示しています。

サーバー側では、コードはペイロードに署名するための API エンドポイントを設定し、JWT gem を使用して会社のシークレットでペイロードをエンコードし、エンコードされたトークンをクライアントに返します。

クライアント側のコードでは、署名付きトークンを取得するために、iOS SDK、Android SDK、ウェブ SDK からサーバー API にリクエストを行う例が示されています。

iOS SDK と Android SDK では、コードは API に HTTP POST リクエストを送信し、レスポンスからトークンを取得します。Web SDK では、コードは API に AJAX リクエストを行い、取得したトークンとユーザー情報を CCAI Platform の初期化関数に渡す認証ハンドラを実装します。

サーバー上の API の例

このセクションのコードは Ruby で記述されており、Rails フレームワークを使用しています。

ホスト アプリケーションのベース URL が https://company.com/api/ であるとします。CCAI Platform のペイロードに署名するには、https://company.com/api/ccaip/sign に別の API エンドポイントを追加します。

このコードは、アプリケーションのルートファイルに新しいルートを追加して、/api/ccaip/sign URL への POST リクエストを処理します。

ccaip_controller.rb ファイルは、sign という単一のエンドポイントを持つ CCAIPController クラスを定義します。このエンドポイントは、CCAI Platform のペイロードに署名するために使用されます。

このコードでは、COMPANY_SECRET はペイロードの署名に使用されるシークレットとして定義されています。ペイロードはリクエストの本文から抽出され、UNIQUE-IDENTIFIER、ユーザー名、メールアドレス、電話番号などのさまざまな値が追加されます。

JWT.encode メソッドは、ペイロードと ccaip_secret を JSON ウェブトークン(JWT)にエンコードするために使用されます。これは、トークンキーを含む JSON オブジェクトとしてレスポンスで返されます。

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

# ccaip_controller.rb
class CCAIPController
  def sign
    ccaip_secret = "COMPANY_SECRET"

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

    token = JWT.encode(payload, ccaip_secret)

    render json: {token: token}
  end
end

iOS SDK からの署名

iOS SDK からペイロードに署名する例を次に示します。

ペイロードをリクエスト本文として、URL https://your.company.com/api/ccaip/sign のサーバーに 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/ccaip/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 を使用してペイロードに署名するための Android SDK 関数の実装です。この関数は、ペイロード、ペイロード タイプ、トークン コールバックを入力として受け取ります。ペイロード タイプが UjetPayloadType.AuthToken の場合、Retrofit インスタンスを作成し、それを使用して https://company.com/api API エンドポイントにリクエストを送信してペイロードに署名します。署名付きトークンは、tokenCallback インスタンスの onToken メソッドで返されます。失敗した場合は、「認証に失敗しました」というトースト メッセージが表示されます。

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 Platform に返します。

$(function() {
  UJET.initialize({
    ... // other parameters
    handlers: {
      authentication(callback) {
        // YOU SHOULD HAVE THIS KIND OF API ON YOUR SERVER
        $.ajax({
          type: 'POST',
          url: 'http://company.com/api/ccaip/sign',
          data: JSON.stringify({
            payload: {
              identifier: 'UNIQUE-Identifier',
              name: 'Test user'
            }
          }),
          success: function(result) {
            // YOU SHOULD CALL `callback` FUNCTION TO RESPONSE THE AUTHENTICATION REQUEST
            callback({
              token: result.token,
              user: {
                identifier: 'UNIQUE-IDENTIFIER',
                name: 'Test user'
              }
            });
          }
        });
      }
    }
  }).then(function() {
    // successfully initialized
  }).catch(function(error) {
    // HANDLE INITIALIZATION ERROR
    // you can handle an error occurred during initialization
  });
});

認証トークンの交換

CCAI Platform では、ホスト アプリケーションが JWT(JSON Web Token)を使用してエンドユーザーの認証トークンに署名し、エンドユーザーの認証トークンと交換します。JWT は、情報を JSON オブジェクトとして安全に送信するためのオープン標準です。

エンドユーザー認証トークンは、CCAI Platform API へのアクセスに使用されます。このメカニズムは、認証プロセスを保護し、承認されたユーザーのみが API にアクセスできるようにします。