Deck of Cards |
---|
history | false |
---|
id | deck principal |
---|
| Card |
---|
| Para a construção melhor compreensão do nosso aplicativo utilizamos o framework de desenvolvimento Ionic na versão 5. Ele é considerado um framework do tipo híbrido, onde temos uma solução web e nativa trabalhando em conjunto. A sua principal característica é a utilização de uma Webview (uma espécie de container) para a renderização dos elementos na tela. Dentre os seus principais benefícios, estão o desenvolvimento mais rápido (utiliza recursos amplamente utilizados no mercado HTML, CSS e Javascript) e trabalhar com multiplataforma (Android e iOS) com apenas um único projeto. No projeto do Meu RH utilizamos o Ionic como um projeto full Angular, porém ele permite a integração também com outros frameworks como React, Vue, Stencil, etc. A parte de comunicação para consumir os recursos do celular é feita pelo Cordova, que conta com diversos plug-ins dentre eles a Geolocalização, biometria, câmera, arquivos do celular e outros. O Ionic também conta com uma ampla biblioteca de componentes que podem ser reaproveitados e combinados para criar novas funcionalidades. O projeto está localizado no repositório MeuRH no AzureDevops. Image Removed A estruturação do nosso app contempla hoje a apenas as páginas relacionadas a login (Login, Esqueceu a Senha, Alterar a senha no primeiro login), a parte de configurações (Configuração de ambiente, Visualização/Compartilhamento de QR-Code, menus de ajuda) e as telas de erros exibidas. Todas as outras funcionalidades do Meu RH são renderizadas pelo projeto de Portais através de um browser que é aberto dentro do aplicativo. Como utilizamos a biblioteca do PO-UI no projeto de Portais e ela é totalmente responsiva, ela adquiri a forma de um aplicativo mobile. Image Removed Porém ao abrir o browser, ficamos com duas webviews diferentes (A própria do Ionic e a outra do browser). Quem acessa os recursos do celular é a própria Webview do Ionic ou o Cordova e por isso o browser onde o portal acessa não tem acesso direto a esses recursos. Porém, sabemos que dentro do aplicativo consumimos esses recursos da mesma forma (Ex: Batida por geolocalização). Para isso funcionar, criamos uma espécie de fila de eventos entre as duas webviews, sendo que sempre quando o portal precisa de algum recurso do celular ele posta uma mensagem na fila de eventos (onde a webview do ionic está sempre escutando), o Ionic solicita o recurso/ação e devolve uma mensagem de resposta para a webview do portal: Image Removed Foi criado um contrato de mensagem nos dois projetos para que os dois lados possam saber o que está sendo solicitado e o que deve ser retornado: Projeto de portais solicitando geolocalização: Image Removed Projeto do app recebendo a solicitação e verificando qual o evento recebido: Image Removed Utiliza o plugin do Cordova para recuperar a geolocalização e emite a resposta na fila de eventos para o portal: Image Removed Projeto de portais recebendo a resposta do Ionic. Seta a informação de geolocalização e exibe a localização no mapa renderizado na tela: Image Removed Em relação a comunicação com o backend, o formato se assemelha a versão de Portal do Meu RH, inclusive a parte que ele renderiza o portal pelo browser utiliza todo o mecanismo do projeto de Portais. Porém, algumas API's estão também do lado do Ionic, por exemplo a API de autenticação. Dessa forma, temos um serviço genérico que é capaz de identificar qual o ERP e a partir disso definir qual a url base para realizar as requisições para o backend. A diferença é que agora todas as requisições provenientes do Ionic exigem o mecanismo de CORS (melhor detalhado na sessão de CORS). Dentre as três linhas de produto temos dois tipos de mecanismos, para RM e Protheus utilizamos um Bearer Token e em Datasul utilizamos Basic Authentication (Cookies). Em ambos os mecanismos os objetos de autenticação são compartilhados entre as duas webviews, visto que são necessários nos dois lados: Image Removed | Card |
---|
| Para utilizar a versão atual do aplicativo é necessário que o CORS esteja corretamente configurado, conforme as documentações abaixo: - Configuração do CORS no JBOSS - Configuração do CORS no TOMCAT A autenticação no DATASUL ocorre via cookie. Expandir |
---|
| É realizado uma requisição POST em /dts/portal-hcm/rest/auth/login. É enviado os dados do usuário via request payload: Image Removed A resposta deverá possuir http status 200 e o seguinte corpo: Image Removed Caso as credenciais estejam incorretas será retornado http status 500 com o seguinte corpo: Image Removed Caso o login tenha acontecido com sucesso é transmitido as credenciais do usuário via mensagem entre a webview do mobile e webview do portal. |
Expandir |
---|
| É realizado uma requisição GET em /api/rh/v1/login/auth/[USUARIO]. A autenticação ocorre via basic auth definido pelo frame. A resposta deverá possuir http status 200 e o seguinte corpo: Image Removed Caso as credenciais estejam incorretas será retornado http status 401 com o corpo vazio. Caso o retorno seja status 503: Image Removed É necessário verificar se não há problemas no contexto rest do ambiente. Para isso envie a requisição protocolo://IP:PORTA/api/btb/v1/companies no postman, o retorno deve ser parecido com: Image Removed Se o retorno for 503, o item deve ser analisado pela equipe de framework. Login com SSO-FILTER ativo (passando pela página de login do frame): É preenchido automaticamente as credenciais do usuário na página de login do frame. Caso aconteça algum erro de autenticação nessa página a página será exibida para o usuário (ocasionando o que os usuários acreditam ser o bug de login em 2 telas). Login com SSO-FILTER desativado: Caso o login tenha acontecido com sucesso é transmitido as credenciais do usuário via mensagem entre a webview do mobile e webview do portal.
Card |
---|
| É necessário que o CORS esteja corretamente configurado e utiliza bearer token. |
do Meu RH, será feito um breve conceito do que é Aplicativo Nativo, Aplicativo Híbrido, IONIC, IONIC CLI, Capacitor, CAPACITOR CLI e Gradle. O que é um aplicativo nativo?Aplicativo nativo é desenvolvido na linguagem exclusiva do determinado sistema operacional (Android ou IOS), explorando todas as potencialidades daquele sistema. Como é desenvolvido com linguagens nativas, o desenvolvedor consegue integrar com funcionalidades nativas (GPS, Câmera, etc.) com uma maior abrangência e customização das bibliotecas do dispositivo. Para Android é desenvolvido com Java ou Kotlin e para o IOS com Swift. O que é um aplicativo híbrido?Aplicativo hibrido é desenvolvido em uma única linguagem ou framework, possuindo acesso a camadas nativas dos aparelhos e sendo possível o funcionamento em ambos sistemas operacionais com o mesmo código. É comum que ele seja desenvolvido com HTML, CSS e Javascript e o Framework envolvido, pois em tempo de build o mesmo realiza a conversão para a linguagem nativa do sistema operacional em que ele será reproduzido. O que é o IONIC?IONIC é um framework para desenvolvimento híbrido, que abstrai as camadas nativas dos sistemas operacionais, disponibilizando um kit de UI com código aberto para desenvolver aplicativos móveis de alto desempenho ou somente WEB. Nele é possível utilizar frameworks e bibliotecas Javascripts, como Angular, Vue e React. O IONIC disponibiliza um kit de componentes para interação da interface com o usuário (Ui Components), unindo a ele a tematização destes componentes. A imagem abaixo ilustra de forma abstrata, qual a responsabilidade do IONIC durante o seu desenvolvimento com uma tecnologia WEB: Image Added Para a comunicação com funcionalidades nativas do dispositivo o IONIC, o mesmo sugere o Capacitor como intermediador. IONIC CLIIONIC CLI é a Interface de linha de comando do IONIC, qualquer funcionalidade que você tenha que utilizar do mesmo, como build, subir localmente o aplicativo, informações do aplicativo e versionamento será por ele. É uma ferramenta que abstrai a complexidade dos comandos para uma interface em linha de comando. Abaixo é possível ver suas funcionalidades: Image Added O que é o Capacitor?Projeto de código aberto que executa aplicativos WEB modernos nativamente em IOS e Android. Capacitor além de otimizar a implantação de softwares com tecnologia WEB nos aplicativos móveis de forma nativa, o mesmo fornece plug-ins que possuem acesso aos recursos nativos do determinado dispositivo, como câmera, localização, biometria e etc. O mesmo possui plug-ins oficiais e também da própria comunidade na qual a empresa não se responsabiliza, mas realiza a indicação. Image Added Na imagem acima, é possível compreender que o WEB APP é criado por uma tecnologia WEB (Angular, React ou Vue) na qual está dentro do ambiente do IONIC Framework. Logo o capacitor fornece API’S, em formato de plug-ins (dependências) que consegue abstrair e disponibilizar informações/funções da camada nativa do dispositivo. E está abstração é fornecida em tempo de execução. Abaixo está a lista dos plug-ins utilizados no Meu RH e uma breve explicação de seu uso no aplicativo: Plugin | Funcionalidade | Origem |
---|
capacitor-native-settings | Acessar as configurações do dispositivo. | Oficial | capacitor-plugin-webview-cache | Apagar cache da webview. | Oficial | capacitor-root-jailbreak-detector | Identifica permissões de Root ou Jailbreak no dispositivo. | Usuário do github | aparajita/capacitor-biometric-auth | Obtem o recurso de biometria. | Usuário do github | awesome-cordova-plugins/chooser | Recurso de transferência de arquivo. | Oficial | awesome-cordova-plugins/in-app-browser | Abrir um site web no dispositivo. | Oficial | capacitor-community/file-opener | Abrir arquivos no dispositivo. | Comunidade | capacitor-community/native-market | Redirecionar o aplicativo para lojas GooglePlay e AppleStore. | Comunidade | capacitor-firebase/messaging | Mensageiro de notificações push no dispositivo. | Comunidade | capacitor-mlkit/barcode-scanning | Escaneador de QR Code. | Usuário do github | capacitor/app-launcher | Acessar um aplicativo das lojas GooglePlay e AppleStore pelo Meu RH. | Oficial | capacitor/camera | Obtêm o recurso de câmera. | Oficial | capacitor/filesystem | Recursos para uso de arquivos no aplicativo. | Oficial | capacitor/geolocation | Obtêm o recurso da localização. | Oficial | capacitor/keyboard | Obtêm recursos do teclado do dispositivo. | Oficial | capacitor/network | Obtêm recursos da internet do dispositivo. | Oficial | capacitor/preferences | Banco de dados para armazenamento de informações do aplicativo. | Oficial | capacitor/push-notifications | Obtêm informações para o Push Notification. | Oficial | capacitor/share | Compartilhamento de arquivos do aplicativo para o dispositivo. | Oficial | capacitor/splash-screen | Acessa funcionalidades da splash-screen do aplicativo. | Oficial | capacitor/status-bar | Acessa funcionalidades da barra superior do dispositivo. | Oficial | cordova-plugin-nativestorage | Banco de dados para armazenamento de informações do aplicativo. | Oficial | cordova-sqlite-storage | Banco de dados para armazenamento de informações do aplicativo. | Oficial | localforage-cordovasqlitedriver | Driver para uso do SQLite no Capacitor. | Oficial |
O que é o CAPACITOR CLI?Ferramenta de interface de linha de comando, responsável por fornecer funções que auxiliarem no seu desenvolvimento com o Capacitor. Todo o comando feito por ela sempre será iniciado com ionic e ao lado a abreviação do Capacitor cap, exemplo: ionic cap build. Segue abaixo alguns comandos que serão utilizados durante o desenvolvimento: ionic cap sync: Sincroniza as alterações feitas do projeto IONIC com o Capacitor, como inserção, modificação ou exclusão de permissões e plug-ins. Em cada alteração citada, será obrigatório realizar o sincronismo neste comando e checar o log para validação de alguma inconsistência na configuração do projeto. ionic cap build <plataforma>: Realiza o build do projeto, verificando se o código compilado está coerente e abrirá a IDE (Android Studio ou XCode) para utilização do aplicativo compilado. ionic cap run: Irá executar o aplicativo em qualquer plataforma disponibilizada, como emulador ou dispositivo físico. ionic cap update <plataforma>: Um sucessor do sync para atualização dos plug-ins e dependências que foram alteradas/modificadas no package.json do projeto. O que é Gradle?É uma ferramenta utilizada pelo Capacitor de forma padrão, para trazer maior velocidade e flexibilidade na automação de construção e empacotamento do código do aplicativo. É responsável por compilar todo o código do projeto (IONIC e plug-ins do Capacitor) e gerar um único executável, sendo da extensão. apk ou .aab. Sendo usado somente em projetos Android, ele engloba toda a configuração do dispositivo nativo, desde permissões, inserção de dependências, configuração de versionamento e assinatura do aplicativo para colocar o mesmo na PlayStore. Estrutura de pastas e arquivos do gradle: Image Added Seguindo a partir da raiz da pasta android, nós temos os arquivos/pastas e suas responsabilidades: .gradle, build, capacitor-cordova-android-plugins: São pastas geradas a partir do build do gradle, responsáveis por guardar informações temporárias, hashs dos plug-ins. gradle.properties: responsável por guardar variáveis de configuração da aplicação Android, como informações e senhas para a assinatura do aplicativo antes de inserir o aplicativo na loja. variables.gradle: responsável por guaradar variáveis de versionamento dos SDK do Android. app/build: está pasta guardará o arquivo compilado do build do Gradle (sendo .apk ou .aab). Importante sempre excluir ela antes gerar um novo arquivo compilado para evitar problemas com cache. app/build.gradle: guardará informações como versionamento do aplicativo, identificador único e configurações para compilação debug ou release. app/google-services.json: arquivo de configuração do push notification. app/src/main/res: ícones que será utilizado no dispositivo a partir do tamanho do dispositivo. app/src/main/AndroidManifest.xml: Arquivo responsável por toda a configuração de permissão e customização de ícones ou plug-ins.
Arquitetura do aplicativo Meu RHPara a construção do nosso aplicativo utilizamos o framework de desenvolvimento IONIC na versão 7 e Angular na versão 15. A parte de comunicação para comunicar com recursos nativos é feita pelo Capacitor. O projeto está localizado no repositório MeuRH no AzureDevops. O aplicativo hoje contempla com as telas de: Autenticação: Login, Esqueceu a Senha, Alterar a senha e Home. Configurações: Configuração de ambiente, Visualização/Compartilhamento de QR-Code e telas de ajuda. Todas as outras funcionalidades do Meu RH são renderizadas pelo projeto de Portais através de um browser que é aberto dentro do aplicativo. Como utilizamos a biblioteca do PO-UI no projeto de Portais e ela é totalmente responsiva, se adaptando ao tamanho do dispositivo mobile. Image Added Porém ao abrir o browser, ficamos com duas Webviews diferentes (A própria do IONIC e a outra do browser). Quem acessa os recursos do celular é a própria Webview do IONIC ou o Capacitor e por isso o browser onde o portal acessa não tem acesso direto a esses recursos. Porém, sabemos que dentro do aplicativo consumimos esses recursos da mesma forma (Ex: Batida por geolocalização). Para isso funcionar, criamos uma espécie de fila de eventos entre as duas webviews, sendo que sempre quando o portal precisa de algum recurso do celular ele posta uma mensagem na fila de eventos (onde a Webview do IONIC está sempre escutando), o IONIC solicita o recurso/ação e devolve uma mensagem de resposta para a Webview do portal:
Image Added
Foi criado um contrato de mensagem nos dois projetos para que os dois lados possam saber o que está sendo solicitado e o que deve ser retornado: Projeto de portais solicitando geolocalização: Image Added Projeto do app recebendo a solicitação e verificando qual o evento recebido: Image Added Utiliza o plugin do Capacitor para recuperar a geolocalização e emite a resposta na fila de eventos para o portal: Image Added Projeto de portais recebendo a resposta do IONIC. Seta a informação de geolocalização e exibe a localização no mapa renderizado na tela: Image Added
Em relação a comunicação com o backend, o formato se assemelha a versão de Portal do Meu RH, inclusive a parte que ele renderiza o portal pelo browser utiliza todo o mecanismo do projeto de Portais. Porém, algumas API's estão também do lado do IONIC, por exemplo a API de autenticação. Dessa forma, temos um serviço genérico que é capaz de identificar qual o ERP e a partir disso definir qual a url base para realizar as requisições para o backend. A diferença é que agora todas as requisições provenientes do IONIC exigem o mecanismo de CORS (melhor detalhado na sessão de CORS). Dentre as três linhas de produto temos dois tipos de mecanismos, para RM e Protheus utilizamos um Bearer Token e em Datasul utilizamos Basic Authentication (Cookies). Em ambos os mecanismos os objetos de autenticação são compartilhados entre as duas webviews, visto que são necessários nos dois lados:
Image Added
Link do repasse sobre os tópicos acima: https://drive.google.com/file/d/15UOFr5KBxQQXdhuClExyS6dyWO42bbtu/view?usp=sharing
|
Card |
---|
| Para utilizar a versão atual do aplicativo é necessário que o CORS esteja corretamente configurado, conforme as documentações abaixo: - Configuração do CORS no JBOSS - Configuração do CORS no TOMCAT A autenticação no DATASUL ocorre via cookie.
Expandir |
---|
| É realizado uma requisição POST em /dts/portal-hcm/rest/auth/login. É enviado os dados do usuário via request payload: Image Added A resposta deverá possuir http status 200 e o seguinte corpo: Image Added Caso as credenciais estejam incorretas será retornado http status 500 com o seguinte corpo: Image Added Caso o login tenha acontecido com sucesso é transmitido as credenciais do usuário via mensagem entre a webview do mobile e webview do portal. |
Expandir |
---|
| É realizado uma requisição GET em /api/rh/v1/login/auth/[USUARIO]. A autenticação ocorre via basic auth definido pelo frame. A resposta deverá possuir http status 200 e o seguinte corpo: Image Added Caso as credenciais estejam incorretas será retornado http status 401 com o corpo vazio. Caso o retorno seja status 503: Image Added É necessário verificar se não há problemas no contexto rest do ambiente. Para isso envie a requisição protocolo://IP:PORTA/api/btb/v1/companies no postman, o retorno deve ser parecido com: Image Added Se o retorno for 503, o item deve ser analisado pela equipe de framework.
Login com SSO-FILTER ativo (passando pela página de login do frame): É preenchido automaticamente as credenciais do usuário na página de login do frame. Caso aconteça algum erro de autenticação nessa página a página será exibida para o usuário (ocasionando o que os usuários acreditam ser o bug de login em 2 telas).
Login com SSO-FILTER desativado: Caso o login tenha acontecido com sucesso é transmitido as credenciais do usuário via mensagem entre a webview do mobile e webview do portal. |
|
Card |
---|
| É necessário que o CORS esteja corretamente configurado e utiliza bearer token. |
Card |
---|
| Desde 09/2021 estamos utilizando nosso aplicativo com o framework Ionic na versão 5. Em relação a versão anterior, tivemos algumas mudanças e as principais delas foram a utilização do mecanismo de CORS, a autenticação por bearer token e a nova forma de comunicação entre o aplicativo e o servidor de aplicação. CORSPara atender o correto funcionamento do mecanismo de CORS e mantendo a infraestrutura que os clientes já possuíam, estamos utilizando agora o modelo de API's do host disponibilizadas pelo nosso time de framework. Além disso, caso o servidor web utilizado seja IIS, realizar a instalação do módulo adicional de CORS https://www.iis.net/downloads/microsoft/iis-cors-module. Maiores informações sobre o mecanismo de CORS estão na seção relacionada. Para o correto funcionamento do CORS em RM, são necessários 3 cabeçalhos na resposta das requisições de OPTIONS: Image Added Bearer tokenOutra novidade na versão do Ionic 5 é a utilização do bearer token para autenticação do usuário ao invés do processo de basic authentication. A bearer authentication (também chamada de autenticação por token) é um esquema de autenticação HTTP que envolve tokens de segurança chamados bearer tokens. O nome "Bearer token" pode ser entendido como "dar acesso ao portador deste token". O bearer token é uma string criptografada, gerada pelo servidor em resposta a uma solicitação de login. O client deve enviar este token no cabeçalho de autorização ao fazer solicitações para recursos protegidos. Utilizamos a API Autorização / Autenticação Basic e Bearer Token que retorna um token contendo as informações do usuário e outras claims que são relevantes para ele. Como funciona a comunicação entre o IIS e o servidor de aplicação?Na versão anterior do aplicativo, utilizavamos a camada de API's do FrameHTML para consumir os serviços necessários. Na nova versão, consumimos as API's que estão na camada do host para recuperar as informações necessárias. Image Added
O endereço de acesso as API's do host é diferente da camada de API's do FrameHTML e não poderíamos realizar alterações de infraestrutura nesse aspecto, pois obrigaria o cliente a gerar novamente o QR Code de ambiente. Dessa forma, estamos utilizando a camada de FrameHTML como uma espécie de client para o host, sendo que todas as requisições ainda são encaminhadas para a camada de FrameHTML e de lá são redirecionadas para o host. Para realizar a comunicação entre a camada FrameHTML e a camada do host são utilizadas as portas de API configuradas dentro dos serviços de host. Para isso, é importante se atentar que caso os servidores de aplicação e de portal sejam separados, não pode haver qualquer tipo de bloqueio sobre as portas de API do host e o servidor de portal deve ser capaz de se comunicar através delas. Para realizar a diferenciação, agora temos 3 controllers que fazem todo o processo. O primeiro deles é o controller padrão na camada FrameHTML e que atende o Portal quando utilizamos a autenticação via Cookie. Note que chamamos o server rest diretamente através do método "RetornaListaPermissoesUsuario" nesse caso: Image Added Ainda na camada FrameHTML, temos o segundo controller. Esse é responsável por atender as requisições de Portal (quando utilizamos autenticação via Token) e o aplicativo com Ionic na versão 5. Ele é responsável por direcionar a requisição para o host através do método "RedirectRequestToNewApiModel". Note que o prefixo dele tem a palavra "new", justamente para segmentar quando deve vir para esse controller ou para o padrão: Image Added O terceiro controller está na camada do host. Ele é bem similar ao primeiro, porém ja conta com todos os benefícios de estar na camada host. Além disso, ele está atendendo ao redirecionamento realizado pelo segundo controller: Image Added Para validar o funcionamento do aplicativo na nova versão, foram desenvolvidos dois scripts dentro da ferramenta Postman, que tem como objetivo simular as principais requisições realizadas pelo aplicativo. Um desses scripts simula de fato o comportamento do app, validando o login, CORS e o consumo de serviços em geral (Pode ser executado de qualquer máquina). Já o outro script tem como objetivo consumir algumas das api's que estão dentro do host (Precisa ser executado de dentro da máquina onde exista o serviço de host). O passo-a-passo para executar os scripts estão no documento https://docs.google.com/document/d/1Jr7It3jhl2aUJBpy9T4c7QtxTU51J9SlGLy8JDsQ8PA/edit?usp=sharing. Caso algum teste que seja executado pelo Postman falhe, significa que algum tipo de problema está impedindo o funcionamento correto do aplicativo. Por padrão, todas as API's (exceto a de healthcheck) não retornam informações detalhadas de erro por motivos de segurança. Caso seja necessário obter mais informações para algum tipo de erro nas API's em geral, basta adicionar a tag <add key="ShowCompleteLogErrorMyHr" value="true" /> dentro do Web.config na pasta FrameHTML: Image Added
Configurações de ambiente para o Ionic 5Pelas especificações de infraestrutura dos clientes, já temos algumas ações mapeadas que podem resolver os problemas de configuração de ambiente. O primeiro passo é seguir os passos descritos no KCS e realizar todas as configurações descritas. Dentre os casos mapeados, temos: Aviso |
---|
OBS: Em todos os cenários mapeados, é necessário seguir os passos do KCS. Além disso, a reserva das portas deve ser feita em todos os servidores que possuam serviços ativos de host. |
Portal e biblioteca instalados no mesmo servidorSeguir apenas o KCS Portal e biblioteca instalados em servidores distintosA primeira verificação que deve ser feita é se o servidor de portal consegue "atingir" o servidor de aplicação e como ele faz isso (Através de IP, hostname, DNS, etc). Além disso, é necessário que a comunicação entre o servidor de portal e o de aplicação seja realizada através das portas API configuradas no serviços de host. Caso exista algum mecanismo de segurança entre a comunicação dos dois servidores (firewall, antivírus, proxy, etc) é necessário criar regras para liberar as portas API, caso contrário o aplicativo não irá funcionar. Por padrão o servidor de portal tentará se comunicar com o servidor de aplicação através do hostname. Se não for adequado para a configuração do cliente a utilização do hostname, será necessário adicionar a tag Host dentro dos arquivos RM.Host.Service.exe.config: Image Added Outras configuraçõesExistem algumas configurações que podem ser utilizadas independente de como o cliente organizou sua infraestrutura. Abaixo listamos algumas das que já foram mapeadas. WebService - ServicesHostNameEm casos onde tenha WebService configurado através da tag ServicesHostName no RM.Host.Service.exe.config, a comunicação será feita através do endereço do WebService utilizando as portas de API configuradas no serviço de host. Image Added Aviso |
---|
OBS: Caso o cliente utilize a tag <add key="EnableWSSecurity" value="true" />, onde habilita a comunicação segura no host, as requisições entre o servidor de portal e o servidor de aplicação utilizaram o protocolo HTTPS. Nesses casos é obrigatória a configuração da tag ServicesHostName pois o domínio precisa ser certificado. |
SubDomainMask ou múltiplas pastas FrameHTMLExistem casos onde o cliente utiliza apenas um servidor de aplicação que atende a diversos servidores de portal. Ele pode utilizar a configuração de Multi Tenancy(Configurando o RM Multi Tenancy (Multi Alias)) ou replicar diversas pastas FrameHTML apontando para o servidor de aplicação. Nesses casos não se pode utilizar a tag DefaultDB dentro dos serviços de host e sim a tag ServiceAlias dentro do arquivo Web.config na pasta FrameHTML. Além disso, é necessário adicionar a tag <add key="ConsiderServiceAliasMyHr" value="true" /> dentro do arquivo Web.config (Caso existam réplicas da pasta FrameHTML, copiar para todos). Image Added Clientes que utilizam Proxy Reverso ou mecanismos de encaminhamentoCaso os cabeçalhos de CORS não estejam sendo repassados corretamente para o client (teste pode ser feito pelo script do Postman), mesmo criando regras de encaminhamento, é necessário fazer uma configuração adicional dentro do IIS. Após realizar a instalação do módulo adicional de CORS https://www.iis.net/downloads/microsoft/iis-cors-module, é necessário adicionar as linhas dentro do web.config dentro da pasta FrameHTML na seção system.webServer Bloco de código |
---|
language | xml |
---|
title | Configuração CORS IIS |
---|
| <system.webServer>
<cors enabled="true">
<add origin="http://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
<add origin="ionic://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
<add origin="capacitor://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
</cors>
</<system.webServer> |
|
Card |
---|
| O que é CORS?O CORS (Cross-origin Resource Sharing) é um mecanismo utilizado pelos navegadores para compartilhar recursos entre diferentes origens. O CORS é uma especificação do W3C e faz uso de headers do HTTP para informar aos navegadores se determinado recurso pode ser ou não acessado. Image Added Requisição PreflightÉ necessário sempre verificar se as requisições preflight estão sendo feitas e o retorno deve conter os cabeçalhos necessários de CORS. Por isso, é importante verificar que eles estão sendo retornados de maneira correta e que nenhum tipo de mecanismo de segurança (firewall, antivírus, proxy, etc) estejam barrando os headers. Os principais headers de response de CORS são: Header | Descrição |
---|
Access-Control-Allow-Origin | Especifica a origem permitida, podendo ser http://localhost ou * para permitir qualquer uma | Access-Control-Allow-Methods | Métodos que são permitidos para acessar aquele recurso (GET, POST, PUT, DELETE, etc) | Access-Control-Allow-Headers | Quais headers são permitidos na requisição (Headers convencionais e simples já são permitidos) | Access-Control-Allow-Credentials | Se a requisição deve ser feita com credenciais (true ou false) | Access-Control-Expose-Headers | Especifica quais headers o browser pode ter acesso | Access-Control-Max-Age | Tempo de vida do resultado da requisição de OPTIONS |
Os principais headers de request de CORS são: Header | Descrição |
---|
Origin | Especifica a origem do request | Access-Control-Request-Method | Especifica qual o método será usado para requisição seguinte a OPTIONS | Access-Control-Request-Headers | Especifica quais os headers diferentes dos convencionais que serão enviados na requisição |
A requisição de preflight nem sempre é realizada, existem alguns casos que são consideradas como requisições simples. São elas: Quando o método é: E possuir apenas esses headers: - Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
E o header Content-Type é: - application/x-www-form-urlencoded
- multipart/form-data
- text/plain
E não utilizar ReadableStream ou event listeners em XMLHttpRequestUpload.
Porém, em outros casos a requisição de preflight é sempre realizada. São eles: O método é: - PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
Ou se tiver um header diferente de: - Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
Ou se o header Conten-Type tiver um valor diferente dos listados abaixo: - application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Ou se utilizar ReadableStream ou event listeners em XMLHttpRequestUpload. IONIC e CORSNa versão 5 do Ionic todas as requisições qualificadas nos critérios acima, utilizam o mecanismo de CORS. Para isso, os backends devem estar preparados para responder de maneira correta as requisições do tipo OPTIONS. No caso do Ionic temos duas origens diferentes para cada um dos tipos de plataforma, Android e iOS: Plataforma | Origem |
---|
Android | http://localhost | iOS | ionic://localhost |
Para testar se o servidor está com CORS configurado corretamente, basta fazer uma requisição POST/PUT/DELETE em alguma URL da API colocando o Header "Origin" com valor "http://localhost". Por exemplo: Image Added
A resposta do servidor deverá possuir em seu header "Access-Control-Allow-Origin" com "http://localhost".
Image Added Caso o servidor não responda da maneira esperada, o CORS não está configurado corretamente e ocorrerá erros no login do mobile. |
Card |
---|
label | Ambiente, usuário e senha de clientes |
---|
| Existem situações onde ocorrem problemas que são intermitentes e/ou temos dificuldades de simular internamente. Como o Meu RH é uma aplicação on premises não temos controle sobre o que é trafegado no ambiente dos clientes. Dessa forma, quando não reproduzimos o problema internamente, temos algumas opções: - Colocar logs no fonte, porém isso gera riscos no ambiente do cliente por ter que adicionar lib/fonte/dll fora da expedição padrão
- Debugar no ambiente e máquina do cliente, assim ele consegue adicionar o usuário e senha. Isso funciona apenas no browser, tem limitações que barram algumas threads e causa lentidão extrema no ambiente
- Cliente passar ambiente na internet, usuário e senha. Porque isso é necessário:
- não é possível criar usuário de testes em ambientes de homologação e produção devido implicações do esocial
- certas situações podem ocorrer devido hierarquia na qual o colaborador está inserido
- em problemas que ocorrem no app, além dos dispositivos iPhone e Android, é necessário também um aparato para realizar a depuração do projeto (mac, apk de debug, android studio configurado, habilitar depuração usb no android, xCode configurado, conta de desenvolvedor iOS)
- Quando o cliente não desejar passar a senha por questões de segurança, utilizar o TOTVS Minha Senha
| Card |
---|
| Desde 09/2021 estamos utilizando nosso aplicativo com o framework Ionic na versão 5. Em relação a versão anterior, tivemos algumas mudanças e as principais delas foram a utilização do mecanismo de CORS, a autenticação por bearer token e a nova forma de comunicação entre o aplicativo e o servidor de aplicação. CORSPara atender o correto funcionamento do mecanismo de CORS e mantendo a infraestrutura que os clientes já possuíam, estamos utilizando agora o modelo de API's do host disponibilizadas pelo nosso time de framework. Além disso, caso o servidor web utilizado seja IIS, realizar a instalação do módulo adicional de CORS https://www.iis.net/downloads/microsoft/iis-cors-module. Maiores informações sobre o mecanismo de CORS estão na seção relacionada. Para o correto funcionamento do CORS em RM, são necessários 3 cabeçalhos na resposta das requisições de OPTIONS: Image Removed Bearer tokenOutra novidade na versão do Ionic 5 é a utilização do bearer token para autenticação do usuário ao invés do processo de basic authentication. A bearer authentication (também chamada de autenticação por token) é um esquema de autenticação HTTP que envolve tokens de segurança chamados bearer tokens. O nome "Bearer token" pode ser entendido como "dar acesso ao portador deste token". O bearer token é uma string criptografada, gerada pelo servidor em resposta a uma solicitação de login. O client deve enviar este token no cabeçalho de autorização ao fazer solicitações para recursos protegidos. Utilizamos a API Autorização / Autenticação Basic e Bearer Token que retorna um token contendo as informações do usuário e outras claims que são relevantes para ele. Como funciona a comunicação entre o IIS e o servidor de aplicação?Na versão anterior do aplicativo, utilizavamos a camada de API's do FrameHTML para consumir os serviços necessários. Na nova versão, consumimos as API's que estão na camada do host para recuperar as informações necessárias. Image Removed O endereço de acesso as API's do host é diferente da camada de API's do FrameHTML e não poderíamos realizar alterações de infraestrutura nesse aspecto, pois obrigaria o cliente a gerar novamente o QR Code de ambiente. Dessa forma, estamos utilizando a camada de FrameHTML como uma espécie de client para o host, sendo que todas as requisições ainda são encaminhadas para a camada de FrameHTML e de lá são redirecionadas para o host. Para realizar a comunicação entre a camada FrameHTML e a camada do host são utilizadas as portas de API configuradas dentro dos serviços de host. Para isso, é importante se atentar que caso os servidores de aplicação e de portal sejam separados, não pode haver qualquer tipo de bloqueio sobre as portas de API do host e o servidor de portal deve ser capaz de se comunicar através delas. Para realizar a diferenciação, agora temos 3 controllers que fazem todo o processo. O primeiro deles é o controller padrão na camada FrameHTML e que atende o Portal quando utilizamos a autenticação via Cookie. Note que chamamos o server rest diretamente através do método "RetornaListaPermissoesUsuario" nesse caso: Image Removed Ainda na camada FrameHTML, temos o segundo controller. Esse é responsável por atender as requisições de Portal (quando utilizamos autenticação via Token) e o aplicativo com Ionic na versão 5. Ele é responsável por direcionar a requisição para o host através do método "RedirectRequestToNewApiModel". Note que o prefixo dele tem a palavra "new", justamente para segmentar quando deve vir para esse controller ou para o padrão: Image Removed O terceiro controller está na camada do host. Ele é bem similar ao primeiro, porém ja conta com todos os benefícios de estar na camada host. Além disso, ele está atendendo ao redirecionamento realizado pelo segundo controller: Image Removed Para validar o funcionamento do aplicativo na nova versão, foram desenvolvidos dois scripts dentro da ferramenta Postman, que tem como objetivo simular as principais requisições realizadas pelo aplicativo. Um desses scripts simula de fato o comportamento do app, validando o login, CORS e o consumo de serviços em geral (Pode ser executado de qualquer máquina). Já o outro script tem como objetivo consumir algumas das api's que estão dentro do host (Precisa ser executado de dentro da máquina onde exista o serviço de host). O passo-a-passo para executar os scripts estão no documento https://docs.google.com/document/d/1Jr7It3jhl2aUJBpy9T4c7QtxTU51J9SlGLy8JDsQ8PA/edit?usp=sharing. Caso algum teste que seja executado pelo Postman falhe, significa que algum tipo de problema está impedindo o funcionamento correto do aplicativo. Por padrão, todas as API's (exceto a de healthcheck) não retornam informações detalhadas de erro por motivos de segurança. Caso seja necessário obter mais informações para algum tipo de erro nas API's em geral, basta adicionar a tag <add key="ShowCompleteLogErrorMyHr" value="true" /> dentro do Web.config na pasta FrameHTML: Image Removed Pelas especificações de infraestrutura dos clientes, já temos algumas ações mapeadas que podem resolver os problemas de configuração de ambiente. O primeiro passo é seguir os passos descritos no KCS e realizar todas as configurações descritas. Dentre os casos mapeados, temos: Aviso |
---|
OBS: Em todos os cenários mapeados, é necessário seguir os passos do KCS. Além disso, a reserva das portas deve ser feita em todos os servidores que possuam serviços ativos de host. |
Portal e biblioteca instalados no mesmo servidorSeguir apenas o KCS Portal e biblioteca instalados em servidores distintosA primeira verificação que deve ser feita é se o servidor de portal consegue "atingir" o servidor de aplicação e como ele faz isso (Através de IP, hostname, DNS, etc). Além disso, é necessário que a comunicação entre o servidor de portal e o de aplicação seja realizada através das portas API configuradas no serviços de host. Caso exista algum mecanismo de segurança entre a comunicação dos dois servidores (firewall, antivírus, proxy, etc) é necessário criar regras para liberar as portas API, caso contrário o aplicativo não irá funcionar. Por padrão o servidor de portal tentará se comunicar com o servidor de aplicação através do hostname. Se não for adequado para a configuração do cliente a utilização do hostname, será necessário adicionar a tag Host dentro dos arquivos RM.Host.Service.exe.config: Image Removed Outras configuraçõesExistem algumas configurações que podem ser utilizadas independente de como o cliente organizou sua infraestrutura. Abaixo listamos algumas das que já foram mapeadas. WebService - ServicesHostNameEm casos onde tenha WebService configurado através da tag ServicesHostName no RM.Host.Service.exe.config, a comunicação será feita através do endereço do WebService utilizando as portas de API configuradas no serviço de host. Image Removed Aviso |
---|
OBS: Caso o cliente utilize a tag <add key="EnableWSSecurity" value="true" />, onde habilita a comunicação segura no host, as requisições entre o servidor de portal e o servidor de aplicação utilizaram o protocolo HTTPS. Nesses casos é obrigatória a configuração da tag ServicesHostName pois o domínio precisa ser certificado. |
SubDomainMask ou múltiplas pastas FrameHTMLExistem casos onde o cliente utiliza apenas um servidor de aplicação que atende a diversos servidores de portal. Ele pode utilizar a configuração de Multi Tenancy(Configurando o RM Multi Tenancy (Multi Alias)) ou replicar diversas pastas FrameHTML apontando para o servidor de aplicação. Nesses casos não se pode utilizar a tag DefaultDB dentro dos serviços de host e sim a tag ServiceAlias dentro do arquivo Web.config na pasta FrameHTML. Além disso, é necessário adicionar a tag <add key="ConsiderServiceAliasMyHr" value="true" /> dentro do arquivo Web.config (Caso existam réplicas da pasta FrameHTML, copiar para todos). Image Removed Clientes que utilizam Proxy Reverso ou mecanismos de encaminhamentoCaso os cabeçalhos de CORS não estejam sendo repassados corretamente para o client (teste pode ser feito pelo script do Postman), mesmo criando regras de encaminhamento, é necessário fazer uma configuração adicional dentro do IIS. Após realizar a instalação do módulo adicional de CORS https://www.iis.net/downloads/microsoft/iis-cors-module, é necessário adicionar as linhas dentro do web.config dentro da pasta FrameHTML na seção system.webServer Bloco de código |
---|
language | xml |
---|
title | Configuração CORS IIS |
---|
| <system.webServer>
<cors enabled="true">
<add origin="http://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
<add origin="ionic://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
<add origin="capacitor://localhost" allowCredentials="true" maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Content-Type" />
</allowHeaders>
<allowMethods>
<add method="GET" />
<add method="PUT" />
<add method="POST" />
<add method="OPTIONS" />
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="Content-Type" />
</exposeHeaders>
</add>
</cors>
</<system.webServer> |
Card |
---|
| O que é CORS?O CORS (Cross-origin Resource Sharing) é um mecanismo utilizado pelos navegadores para compartilhar recursos entre diferentes origens. O CORS é uma especificação do W3C e faz uso de headers do HTTP para informar aos navegadores se determinado recurso pode ser ou não acessado. Image Removed Requisição OPTIONS (Preflight)É necessário sempre verificar se as requisições do tipo OPTIONS (preflight) estão sendo feitas e o retorno deve conter os cabeçalhos necessários de CORS. Por isso, é importante verificar que eles estão sendo retornados de maneira correta e que nenhum tipo de mecanismo de segurança (firewall, antivírus, proxy, etc) estejam barrando os headers. Os principais headers de response de CORS são: Header | Descrição |
---|
Access-Control-Allow-Origin | Especifica a origem permitida, podendo ser http://localhost ou * para permitir qualquer uma | Access-Control-Allow-Methods | Métodos que são permitidos para acessar aquele recurso (GET, POST, PUT, DELETE, etc) | Access-Control-Allow-Headers | Quais headers são permitidos na requisição (Headers convencionais e simples já são permitidos) | Access-Control-Allow-Credentials | Se a requisição deve ser feita com credenciais (true ou false) | Access-Control-Expose-Headers | Especifica quais headers o browser pode ter acesso | Access-Control-Max-Age | Tempo de vida do resultado da requisição de OPTIONS | Os principais headers de request de CORS são: Header | Descrição |
---|
Origin | Especifica a origem do request | Access-Control-Request-Method | Especifica qual o método será usado para requisição seguinte a OPTIONS | Access-Control-Request-Headers | Especifica quais os headers diferentes dos convencionais que serão enviados na requisição | A requisição de OPTIONS nem sempre é realizada, existem alguns casos que são consideradas como requisições simples. São elas: Quando o método é: Possui apenas esses headers: - Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
O header Content-Type é: - application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Não utiliza ReadableStreamou event listeners em XMLHttpRequestUpload. Porém, em outros casos a requisição OPTIONS é sempre realizada. São eles: O método é: - PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
Ou se tiver um header diferente de: - Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
Ou se o header Conten-Type tiver um valor diferente dos listados abaixo: - application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Ou se utilizar ReadableStreamou event listeners in XMLHttpRequestUpload. IONIC e CORSNa versão 5 do Ionic todas as requisições qualificadas nos critérios acima, utilizam o mecanismo de CORS. Para isso, os backends devem estar preparados para responder de maneira correta as requisições do tipo OPTIONS. No caso do Ionic temos duas origens diferentes para cada um dos tipos de plataforma, Android e iOS: Plataforma | Origem |
---|
Android | http://localhost | iOS | ionic://localhost | Para testar se o servidor está com CORS configurado corretamente basta fazer uma requisição POST/PUT/DELETE (não pode GET) em alguma URL da API colocando o Header "Origin" com valor "http://localhost", como por exemplo: Image Removed A resposta do servidor deverá possuir em seu header "Access-Control-Allow-Origin" com "http://localhost". Image Removed Caso o servidor não responda isso o CORS não está configurado corretamente e ocorrerá erros no login do mobile. Card |
---|
| Certificado SSL é um certificado digital que autentica a identidade de um site e possibilita uma conexão criptografada. O termo "SSL" significa "Secure Sockets Layer" (camada de soquete seguro), um protocolo de segurança que cria um link criptografado entre um servidor Web e um navegador Web. Empresas e organizações precisam adicionar certificados SSL aos seus sites para proteger as transações on-line e manter a privacidade e a segurança das informações dos clientes. Verifique o seu certificadoNo nosso aplicativo, em ambas plataformas (Android e iOS) utilizamos um browser para renderizar o nosso aplicativo. Isso implica na validação dos certificados assim como em qualquer site que você acessa normalmente por um browser comum. Para verificar se um determinado certificado é válido, recomendamos a validação através de portais como https://www.ssllabs.com/ssltest/ ou https://www.sslshopper.com/ssl-checker.html Por exemplo, o SSLLabs realiza a geração de um grade/score baseado em uma série de critérios como por exemplo inspeção do certificado e protocolos de criptografia, nos casos abaixo o certificado gratuito ficou grade B, pois nível de criptografia suportado é inferior ao disponível no mercado, nesse link podem ser identificado metodologia de validação: https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide Image Removed Image Removed Image Removed Image Removed E se o meu certificado estiver inválido?A tentativa de utilização de certificados inválidos geram erro no processo de handshake na validação das requisições e geração da chave de sessão entre o cliente requisitante e o servidor, consequentemente todas as suas informações não irão trafegar de modo seguro e criptografado pela rede. No exemplo da imagem abaixo, podemos observar que apesar de ser um certificado valido e configurado no server com sua chave privada, o mesmo não está autorizado a ser utilizado de acordo com o SAN, sendo rejeito pelo browsers no momento de negociação da chave de acesso para a sessão de comunicação. Ou seja, não podemos utilizar esse certificado para ser configurado em um IP externo ou mesmo em qualquer outro subdomínio, sendo assim realize essa verificação e validação para um correto funcionamento do ambiente seguro. Image Removed Certificados SSL MobileAs plataformas de dispositivos móveis (IOS, Android) possuem limitações com relação aos certificados digitais. Por padrão, apenas os certificados homologados por elas são reconhecidos como confiáveis. Em geral, as maiores certificadoras são reconhecidas em ambos sistemas operacionais, porém em caso de dúvidas, procure na sua unidade certificadora para assegurar que seu certificado é homologado para ambas plataformas. Para evitar a aquisição de certificados não homologados e outros problemas relacionados a segurança, é importante consultar a documentação técnica de cada plataforma sobre a lista de certificados reconhecidos como confiáveis: Plataforma | Como consultar |
---|
| iOS | A lista de certificados confiáveis para o iOS está disponível em: Certificados confiáveis IOS. (Esse link é constantemente atualizado. Até a data da escrita dessa documentação a versão é a 14). Além disso, a Apple também instituiu a chamada Política de Transparência de Certificados da Apple, que define algumas diretivas de certificados que são válidos https://support.apple.com/en-us/HT205280. Para verificar se o seu certificado se enquadra nessa política de transparência, utilize a ferramenta https://sslmate.com/labs/ct_policy_analyzer/. | Android | É necessário verificar no aparelho em: Configurações > Segurança > Credenciais Confiáveis Na Aba Sistema existe a lista de certificados confiáveis para aquela versão do Android. Atenção: Cada versão do Android pode ter uma lista de certificados confiáveis diferente. | Alguns sinais são comuns e indicam que o certificado não é válido para utilização em mobile: - Consegue se logar em apenas uma das plataformas pelo aplicativo (Android ou iOS)
- Carregamento com tempo excessivo na tela pós-login até resultar algum erro genérico na tela
- Ao acessar a URL do portal pelo browser do celular, exibe alguma mensagem relacionada a algum problema de segurança:
Image Removed
|
|