A plataforma disponibiliza formas de integrar os dados de autenticação com aplicações de terceiros. Esta integração acontece através do compartilhamento de credenciais.
Com isso quando a plataforma abre uma tela de um sistema externo, através do menu, informações são enviadas para a tela aberta. Essas informações contém :
- URL base da plataforma
- Token de acesso do usuário conectado
Resumidamente, com a URL base montam-se os requests para a plataforma, sendo que em cada request deve ser enviado o token de acesso no HEADER “Authorization” (Bearer).
Em vídeo
Sobre o tutorial
Neste tutorial faremos um projeto FrontEnd que consome a API de usuários da plataforma, para obteção dos dados do usuário logado. O projeto será construído utilizando Angular 9 + Bootstrap 4.5.0.
Pré condições
Para executar este tutorial você deverá ter:
- NodeJs 10 ou superior instalado
- NPM 6 ou superior instalado
- Uma IDE de sua preferência
- Uma conta na Amazon Cloud Services e algum conhecimento acerca dos serviços S3 e CloudFront
Criando o projeto
Para criar o projeto digite:
npm install -g @angular/cli@v9-lts
Isso instalará o Angular cli, responsável por gerar o projeto base.
Digite:
ng new custom-app --routing false --style css
Isso criará o projeto de fato
Entre na pasta do projeto digitando:
cd custom-app
Agora iremos instalar alguns componentes que utilizaremos no projeto:
Instale o componente platform-data:
npm install @seniorsistemas/senior-platform-data --save
Instale o component senior-core:
npm install @seniorsistemas/senior-core --save
Instale o bootstrap:
npm install --save bootstrap@4.5.0
No arquivo src/style.css importe o Bootstrap adicionando ao arquivo a seguinte linha de código:
@import "~bootstrap/dist/css/bootstrap.min.css";
Criando o service que fará a comunicação com a plataforma
Crie um serviço através do comando:
ng generate service app
Abra o arquivo gerado app.service.ts na pasta src/app/ e altere conforme abaixo:
import { Injectable } from '@angular/core'; import { service, user } from '@seniorsistemas/senior-platform-data'; import { SeniorApi, ENVIRONMENTS } from "@seniorsistemas/senior-core"; import { Observable, forkJoin, from } from 'rxjs'; import { concatMap } from 'rxjs/operators'; import { environment } from "../environments/environment"; @Injectable() export class AppService { private seniorApi: SeniorApi; constructor() { this.seniorApi = new SeniorApi(); if(environment.production) { this.seniorApi.environment = ENVIRONMENTS.PROD } else { this.seniorApi.environment = ENVIRONMENTS.DEV } } getUser(): Observable<any> { return from(user.getToken()) .pipe( concatMap(token => { this.seniorApi.accessToken = token.access_token; return from(this.seniorApi.users.getUser()); }) ); } }
A function getUser busca os dados do usuário com a url base e o token, através do componente platform-data e os utiliza para fazer a chamada do endpoint /platform/user/queries/getUser, que retorna os dados do usuário logado.
O response será:
{ "changePassword": false, "properties": [], "admin": false, "allowedToChangePassword": true, "id": "6e17f4b3-536f-441b-9685-9f2790f2a12a", "username": "john.doe", "fullName": "John Doe", "email": "john.doe@senior.com.br", "tenantDomain": "senior.com.br", "tenantName": "senior", "tenantLocale": "pt-BR", "blocked": false, "authenticationType": "G7", "_discriminator": "completeUser" }
Com base na resposta, o sistema que está integrando deverá validar:
- Se o campo “username” (ex: john.doe) existe na base de dados dele
- Se o campo “tenantDomain” ou “tenantName” batem com o usuário da base de dados efetuando o login
Medidas de segurança:
- Sistema sendo integrado faça a requisição para URLs configuráveis, uma vez que para teste será usado um ambiente de homologação.
- O sistema deve validar o tenant do usuário que está logando, para garantir que usuários de mesmo nome façam acesso cruzados em outros tenants.
Agora será necessário adicionar no modulo o novo serviço, altere o arquivo src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { AppService } from './app.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [AppService], bootstrap: [AppComponent] }) export class AppModule { }
Crie o arquivo src/app/user-data.ts:
export class UserData { fullName: string username: string email: string tenantDomain: string tenantName: string tenantLocale: string }
Altere o arquivo src/app/app.component.ts adicionando:
import { Component } from '@angular/core'; import { AppService } from "./app.service"; import { UserData } from "./user-data" @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { userData = new UserData(); constructor(private appService: AppService) { } getLoggedUser() { this.appService.getUser().subscribe((res: any) => { this.userData = res.data; }); } }
Altere também o arquivo src/app/app.component.html
<div class="container" style="text-align: center;"> <div class="col-md-12"> <h1>Aplicação integrada à senior X Platform</h1> </div> <div class="row form-group"> <div class="col-12"> <h4>Clique aqui para obter os dados do usuário logado</h4> <button (click)="getLoggedUser()" class="btn btn-primary">Obter dados</button> </div> </div> <div *ngIf="userData.username"> <div class="row"> <div class="col-6 text-left">Nome Completo:</div> <div class="col-6 text-left">{{userData.fullName}}</div> </div> <div class="row"> <div class="col-6 text-left">E-mail:</div> <div class="col-6 text-left">{{userData.email}}</div> </div> <div class="row"> <div class="col-6 text-left">Usuário:</div> <div class="col-6 text-left">{{userData.username}}</div> </div> <div class="row"> <div class="col-6 text-left">Nome do tenant:</div> <div class="col-6 text-left">{{userData.tenantName}}</div> </div> <div class="row"> <div class="col-6 text-left">Domínio do tenant:</div> <div class="col-6 text-left">{{userData.tenantDomain}}</div> </div> <div class="row"> <div class="col-6 text-left">Locale do tenant:</div> <div class="col-6 text-left">{{userData.tenantLocale}}</div> </div> </div> </div>
Implantando o projeto
Uma vez criada a aplicação faça o deploy da mesma em seu serviço de preferência, lembrando que, o frontend deve estar servido sob https.
Antes de implantar lembre-se de criar o dist do seu frontend. Para isso basta rodar um dos comandos abaixo:
- Caso seja para ambiente de desenvolvimento (platform-homologx): ng build
- Caso seja para produção (api.senior.com.br): ng build –prod
Ambos os comandos vão gerar a pasta dist com os arquivos para serem implantados dentro da plataforma.
Siga os passos do tutorial de implantação de frontend customizado para realizar a implantação do projeto. Implantando o front-end customizado.
Pronto, concluída a configuração do módulo basta acessar sua nova aplicação integrada através do menu.
Os fontes deste tutorial podem ser encontrados no GitHub.