APIs

Integrando com o login da plataforma

2532 views 26/02/2018 14/09/2020 gian-pasqualini 4

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.

Este artigo foi útil para você?