Autenticação de usuário final do SDK

O processo de autenticação do usuário final na Contact Center AI Platform (CCAI Platform) é um método seguro para identificar o usuário que está usando o aplicativo host. O usuário final é identificado por um identificador universal exclusivo (UUID) fornecido pelo aplicativo host. O SDK da plataforma CCAI solicita um JSON Web Token (JWT) assinado pela chave secreta compartilhada (company_secret) e fornecido pelo aplicativo host sempre que a autenticação é necessária. Se o app host fornecer o JWT, o SDK da plataforma CCAI vai iniciar o processo de autenticação e receber um token de autenticação.

Usuário final

O usuário final, nesse contexto, é o usuário do aplicativo host.

Para identificar o usuário final, a plataforma CCAI usa um identificador fornecido pelo app host. Esse identificador precisa ser um identificador universalmente exclusivo (UUID) exclusivo para cada usuário.

O uso de um UUID ajuda a garantir que o usuário final possa ser identificado com precisão e diferenciado de outros usuários, mesmo que o endereço de e-mail mude.

Autenticar com a plataforma CCAI

O JSON Web Token (JWT) é usado para identificar com segurança um usuário ou um aplicativo que faz uma solicitação à plataforma CCAI. O aplicativo host é responsável por fornecer o JWT ao SDK da plataforma CCAI usando um callback. O SDK da plataforma CCAI pede ao aplicativo host para fornecer um JWT usando a chave compartilhada do SDK (sdk_key) sempre que a autenticação for necessária.

Se o aplicativo host forneceu um JWT ao SDK da CCAI Platform pelo callback, o SDK da CCAI Platform começa a autenticar na CCAI Platform e recebe o token de autenticação.

O payload do JWT pode incluir informações como identificador, endereço de e-mail, nome e número de telefone do usuário.O Google Cloud recomenda usar o formato E.164 para números de telefone. Essas informações são usadas para criar uma conta para o usuário ou associá-lo a uma conta na plataforma CCAI.

Se o aplicativo host fornecer um identificador no payload do JWT, a plataforma da CCAI vai usar esse identificador para criar ou associar o usuário a uma conta. Se um identificador não for fornecido, a plataforma CCAI vai criar uma conta anônima para o usuário.

Para mais informações sobre o login com assinatura JWT na plataforma CCAI, consulte a seção Assinatura JWT.

Gerenciar chaves do SDK

Os campos sdk_key_name e sdk_key são elementos importantes de autenticação. Eles identificam sua empresa de maneira exclusiva e são usados para acessar com segurança a API da plataforma CCAI.

Para gerenciar as chaves do SDK, siga estas etapas:

  1. Faça login no portal da plataforma CCAI como um usuário com a função de administrador.

  2. No portal da plataforma CCAI, clique em Configurações > Configurações do desenvolvedor. Se o menu Configurações não aparecer, clique em Menu.

  3. Acesse o painel Chave e código secreto da empresa para gerenciar as chaves do SDK, que são usadas para gerar tokens de autenticação.

Mantenha esses códigos em segurança e compartilhe apenas com pessoas ou sistemas autorizados que precisam de acesso à API da plataforma CCAI. O acesso não autorizado a esses códigos pode comprometer a segurança dos seus dados e sistemas.

Fluxo de trabalho de autenticação

Este é o fluxo de trabalho de autenticação:

  1. A plataforma CCAI fornece um nome de chave do SDK (sdk_key_name) e uma chave do SDK (sdk_key) para o aplicativo host. Elas podem ser encontradas em Configurações > Configurações do desenvolvedor > Chaves do SDK.

  2. Quando o usuário final começa a usar o atendimento ao cliente da plataforma CCAI, o SDK da plataforma CCAI solicita a assinatura do JWT do aplicativo host.

  3. A plataforma CCAI verifica o JWT assinado e emite um token de autenticação do usuário final. Esse processo garante uma autenticação segura e perfeita entre o aplicativo host e o atendimento ao cliente da plataforma CCAI.

Assinatura JWT

O aplicativo host precisa implementar um método de callback para cada plataforma. As seções a seguir fornecem instruções para cada plataforma.

Para processar as informações do usuário final, o app host precisa preencher o payload do JWT. Um payload padrão é fornecido pelo método de callback e pode já conter alguns valores, como o token de push e o nome padrão.

O aplicativo host pode adicionar mais informações sobre o usuário usando nomes de chaves reservadas, como:

  • identificador (opcional)

  • nome (opcional)

  • e-mail (opcional)

  • Número de telefone (opcional, formato E.164)

Por exemplo, para o SDK do iOS, a implementação do método pode ser assim para fins de teste (usando 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);
    }
  }
}

Exemplo para produção

Google Cloud recomenda assinar o payload no lado do servidor para aumentar a segurança. Assim, o segredo da empresa não fica exposto no lado do cliente e pode ser revogado a qualquer momento se for considerado em risco. Essa abordagem oferece mais segurança em comparação com a assinatura do payload no lado do cliente.

Os snippets de código a seguir fornecem exemplos de assinatura do payload no lado do servidor usando o framework Ruby on Rails com a gema JWT e no lado do cliente usando os SDKs para iOS, Android e Web.

No lado do servidor, o código configura um endpoint de API para assinar o payload, usando a gem JWT para codificar o payload com um segredo da empresa e retornar o token codificado para o cliente.

No lado do cliente, o código fornece exemplos de como fazer uma solicitação para a API do servidor dos SDKs do iOS, SDK do Android e Web para recuperar o token assinado.

Nos SDKs do iOS e do Android, o código faz uma solicitação HTTP POST para a API e recupera o token da resposta. No SDK da Web, o código implementa um manipulador de autenticação que faz uma solicitação AJAX à API e transmite o token e as informações do usuário recuperados para a função de inicialização da plataforma CCAI.

Exemplo de API no servidor

O código nesta seção foi escrito em Ruby e usa o framework Rails.

Suponha que o URL base do aplicativo host seja https://company.com/api/. Para assinar o payload da plataforma CCAI, adicione outro endpoint de API em https://company.com/api/ccaip/sign.

O código adiciona uma nova rota ao arquivo de rotas do aplicativo para processar solicitações POST ao URL /api/ccaip/sign.

O arquivo ccaip_controller.rb define a classe CCAIPController, que tem um único endpoint chamado sign. Esse endpoint é usado para assinar um payload para a plataforma CCAI.

No código, COMPANY_SECRET é definido como o secret usado para assinar o payload. O payload é extraído do corpo da solicitação e, em seguida, vários valores são adicionados a ele, por exemplo, UNIQUE-IDENTIFIER, nome de usuário, e-mail e telefone.

O método JWT.encode é usado para codificar o payload e o ccaip_secret em um JSON Web Token (JWT), que é retornado na resposta como um objeto JSON com a chave do token.

 # 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

Assinatura do SDK do iOS

Confira a seguir um exemplo de assinatura de um payload do SDK para iOS.

Ele faz uma solicitação POST ao servidor no URL https://your.company.com/api/ccaip/sign com o payload como o corpo da solicitação. Espera-se que o servidor retorne um token assinado em resposta, que é transmitido ao callback de sucesso na forma da chave "token" em um objeto JSON. Se houver um erro durante a solicitação, ele será transmitido ao callback de falha.

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

Assinatura do SDK do Android

Confira a seguir um exemplo de assinatura de um payload de um SDK do Android.

É uma implementação de uma função do SDK do Android para assinar um payload usando Retrofit, um cliente HTTP para Android. A função usa um payload, um tipo de payload e um callback de token como entrada. Se o tipo de payload for UjetPayloadType.AuthToken, ele vai criar uma instância do Retrofit e usá-la para fazer uma solicitação ao endpoint de API https://company.com/api para assinar o payload. Ele retorna o token assinado no método onToken da instância tokenCallback. Em caso de falha, uma mensagem de aviso "Falha na autenticação" é exibida.

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

Assinatura do SDK da Web

O exemplo a seguir demonstra como assinar o payload no SDK da Web fazendo uma solicitação de API ao servidor com o payload.

O servidor precisa ser configurado para processar a solicitação de API e assinar o payload usando um método seguro. O resultado é retornado à página da Web, que transmite o token assinado de volta à plataforma CCAI usando a função de callback.

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

Troca de token de autenticação

Na plataforma CCAI, o aplicativo host usa JWT (JSON Web Token) para assinar o token de autenticação do usuário final, que é trocado por um token de autenticação do usuário final. O JWT é um padrão aberto para transmitir informações com segurança como um objeto JSON.

O token de autenticação do usuário final é usado para acessar a API da plataforma CCAI. Esse mecanismo ajuda a proteger o processo de autenticação e garantir que apenas usuários autorizados tenham acesso à API.