Autenticación del usuario final

Contact Center AI Platform usa la autenticación del usuario final para identificar de forma segura a las personas que usan tu app host. Este mecanismo garantiza que solo los usuarios autorizados puedan acceder a la API de Contact Center AI Platform y que sus sesiones de chat y datos permanezcan vinculados de forma segura a su identidad específica.

Para identificar a un usuario final, tu app host debe proporcionar un identificador único universal (UUID) que represente a esa persona específica.

Cómo funciona la autenticación en CCAI Platform

La autenticación en la plataforma de la CCAI se basa en un protocolo de enlace seguro que usa un token web JSON (JWT). Un JWT es un estándar abierto que se usa para transmitir información de forma segura como un objeto JSON.

Este es el flujo de autenticación estándar:

  1. La solicitud: Cuando un usuario final comienza a usar el servicio de atención al cliente de la plataforma de CCAI, el SDK de la plataforma de CCAI solicita un JWT firmado desde tu app host.

  2. La firma: Tu app host firma el JWT con el secreto compartido de tu empresa de la plataforma de CCAI (company_secret).

  3. El intercambio: La app host pasa el JWT firmado de vuelta al SDK de CCAI Platform. Luego, el SDK envía este JWT al servidor de la plataforma de CCAI.

  4. La verificación: El servidor de CCAI Platform verifica la firma. Si es válido, la plataforma de la CCAI emite un token de autorización, que le otorga al usuario acceso a la API y lo asocia con su cuenta (o crea una nueva si no existe).

Si tu app host no proporciona un identificador en la carga útil del JWT, CCAI Platform creará una cuenta de invitado anónima para el usuario.

Requisitos previos

Antes de implementar la autenticación, necesitas tus elementos únicos de autenticación del SDK. Estos identifican de forma segura a tu empresa en la API de la plataforma de CCAI.

  1. Accede a la plataforma de CCAI con una cuenta de administrador.

  2. Navega a Configuración > Configuración para desarrolladores > Credenciales de API.

  3. Ubica el nombre de la clave del SDK (sdk_key_name), la clave del SDK (sdk_key) y el secreto de la empresa (company_secret).

Protege estas credenciales. Compártelos solo con sistemas y desarrolladores autorizados.

Guía de implementación para desarrolladores

En la siguiente sección, se describe cómo los desarrolladores deben construir la carga útil del JWT y cómo inicializar el SDK de la plataforma de CCAI en diferentes plataformas.

Requisitos de la carga útil de JWT

Para pasar la información del usuario final a CCAI Platform, tu app host debe construir una carga útil de JWT. El método de devolución de llamada proporciona una carga útil predeterminada (que puede incluir un token de envío y un nombre predeterminado), pero puedes agregar detalles específicos del usuario con las siguientes claves reservadas:

  • identifier (UUID opcional, pero muy recomendado)

  • name (opcional)

  • email (opcional)

  • phone (opcional, debe usar el formato E.164)

  • iss (opcional, nombre de la empresa)

  • iat (obligatorio, marca de tiempo de emisión)

  • exp (obligatorio, marca de tiempo de vencimiento)

Firma del servidor (recomendado)

Ejemplo de API en el servidor (Ruby on Rails)

En este ejemplo, se muestra cómo firmar la carga útil en el servidor con el framework de Ruby on Rails y la gema JWT.

El código configura un extremo de API (/api/ujet/sign) con la gema jwt para codificar la carga útil con un secreto de la empresa y devolver el token codificado al cliente.

Supongamos que la URL base de tu aplicación host es https://company.com/api/. Para firmar la carga útil de la plataforma de CCAI, puedes agregar otro extremo de API en https://company.com/api/ujet/sign.

El código agrega una nueva ruta al archivo de rutas de la aplicación para controlar las solicitudes POST a la URL /api/ujet/sign.

El archivo ujet_controller.rb define la clase UjetController, que tiene un solo extremo, sign, que se usa para firmar una carga útil para CCAI Platform.

En el código, COMPANY_SECRET se define como el secreto que se usa para firmar la carga útil. La carga útil se extrae del cuerpo de la solicitud y, luego, se le agregan varios valores, por ejemplo, UNIQUE-IDENTIFIER, nombre de usuario, correo electrónico y teléfono.

El método JWT.encode se usa para codificar la carga útil y el ujet_secret en un token web JSON (JWT), que luego se devuelve en la respuesta como un objeto JSON con la clave del token.

# 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

Inicialización del cliente

Sigue estos lineamientos para inicializar el SDK para dispositivos móviles de CCAI Platform.

Firma desde el SDK de iOS

En este ejemplo de firma de una carga útil desde el SDK para iOS, se realiza una solicitud POST al servidor en la URL https://your.company.com/api/ujet/sign con la carga útil como cuerpo de la solicitud.

Se espera que el servidor devuelva un token firmado en la respuesta, que luego se pasa a la devolución de llamada de éxito en forma de la clave "token" en un objeto JSON.

Si se produce un error durante la solicitud, se pasa a la devolución de llamada de error.

-   (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];
  }
}

Firma desde el SDK de Android

A continuación, se muestra un ejemplo de cómo firmar una carga útil desde un SDK de Android.

En este ejemplo, se usa Retrofit, un cliente HTTP para Android, para solicitar la carga útil firmada de tu servidor. La función toma una carga útil, un tipo de carga útil y una devolución de llamada de token como entrada.

Si el tipo de carga útil es UjetPayloadType.AuthToken, se crea una instancia de Retrofit, se usa para realizar una solicitud al endpoint de la API de https://company.com/api para firmar la carga útil y se devuelve el token firmado en el método onToken de la instancia de tokenCallback.

En caso de falla, se muestra un mensaje emergente "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();
            }
        });
    }
}

Firma desde el SDK web

En el siguiente ejemplo, se muestra cómo firmar la carga útil en el SDK web realizando una solicitud a la API del servidor con la carga útil.

El servidor debe configurarse para controlar la solicitud a la API y firmar la carga útil con un método seguro. Luego, el resultado se devuelve a la página web, que pasa el token firmado a la plataforma de CCAI a través de la función de devolución de llamada.

$(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
  });
});

Autenticación durante la sesión y reinicialización del SDK

En algunos casos, un usuario final puede iniciar una sesión de chat como invitado (sin autenticar) y verificar su identidad a mitad de la sesión (p.ej., a través de un asistente virtual o una pantalla de acceso a mitad del flujo). Para asegurarte de que la sesión activa se actualice de forma segura y se asocie con el usuario recién autenticado, sigue estos pasos:

Pasos para la autenticación durante la sesión

  1. Inicializa el SDK con un identificador temporal: Cuando el usuario no está autenticado, inicializa el SDK de CCAI Platform con un identificador aleatorio o de invitado.

  2. Dirige al usuario para que se autentique: Guía al usuario a través de tu flujo de autenticación, como un asistente virtual (AV) de CCAI Platform o la pantalla de acceso integrada de tu app.

  3. Actualiza al usuario final a través de la API: Después de que el usuario se autentique correctamente (y mientras aún esté en el agente virtual o en el flujo de autenticación), tu backend debe llamar a la API de CCAI Platform Apps para actualizar la sesión de chat del usuario final con su identificador verdadero.

  4. Reinicializa el SDK con un nuevo JWT: Después de una actualización exitosa del backend, genera un nuevo JWT para el usuario autenticado. Vuelve a inicializar el SDK de CCAI Platform llamando al método de inicialización nuevamente con este nuevo JWT.

  5. Deriva la sesión (si se usa un asistente virtual): Si el usuario se autenticó con un asistente virtual, el agente virtual ahora debe derivar al consumidor a la cola de destino final.

Ejemplo (SDK web)

Para volver a inicializar, llama a la función UJET.initialize de nuevo. Esto activará el controlador de autenticación para recuperar el token nuevo.

// 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
});

¿Por qué es necesario?

  • Garantiza que todas las acciones, el enrutamiento y el historial posteriores se asocien de forma segura con el usuario autenticado, en lugar de con una sesión de invitado anónima.

  • Evita la filtración de datos y mantiene registros precisos de los usuarios y del CRM.

Tabla de resumen

Situación Acción obligatoria
El usuario inicia la sesión autenticado Inicializa el SDK con el UUID y el JWT verdaderos del usuario.
El usuario comienza sin autenticarse Inicializa el SDK con un identificador aleatorio o de invitado.
El usuario se autentica durante la sesión Actualiza la plataforma de la CCAI con la API, genera un nuevo JWT y reinicializa el SDK.