Integrando com o login da plataforma


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 { 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/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 https://github.com/dev-senior-com-br/tutorial-integrando-login-plataforma.