developers

Autenticação Angular na Prática

Aprenda como adicionar autenticação de usuário ao Angular usando Observables e HTTP Interceptors. Aprenda a usar a Auth0 para lidar com autenticação de usuário baseada em token no Angular.

Jun 21, 20231 min read

Este guia TypeScript ajudará você a aprender como proteger uma aplicação Angular usando autenticação baseada em token. Você aprenderá como usar o framework Angular para implementar os seguintes recursos de segurança:

  • Como adicionar login, inscrição e logout de usuário para aplicações Angular.
  • Como criar guardas de rota para proteger rotas de aplicação Angular.
  • Como fazer chamadas de API a partir do Angular para solicitar dados de uma API protegida.
  • Como obter informações de perfil de usuário para personalizar uma interface de usuário Angular.

Este guia usa o SDK da Auth0 para Angular que fornece às pessoas desenvolvedoras uma API de alto nível para lidar com muitos detalhes da implementação de autenticação de usuário. Você pode proteger suas aplicações Angular seguindo as melhores práticas de segurança e ainda escrever menos código.

Configuração Rápida Do Angular

Com a ajuda da Auth0, você não precisa ser especialista em protocolos de identidade, como OAuth 2.0 ou OpenID Connect, para entender como proteger sua stack de aplicações web.

Você começa integrando sua aplicação Angular com a Auth0. Sua aplicação redirecionará os usuários para uma página de login personalizável sempre que precisarem fazer login. Após seus usuários fazerem login com sucesso, a Auth0 os redirecionará de volta para a sua aplicação Angular, retornando JSON Web Tokens (JWTs) com informações de autenticação e de usuário.

Obtenha a aplicação Angular inicial

Criamos um projeto inicial usando a linha de comando do Angular (Angular CLI) para te ajudar a aprender os conceitos de segurança do Angular por meio da prática. Você pode se concentrar em construir componentes e serviços Angular e serviços para proteger sua aplicação.

Comece clonando o repositório

spa_angular_typescript_hello-world
no branch
starter
.

git clone -b starter git@github.com:auth0-developer-hub/spa_angular_typescript_hello-world.git

Depois de clonar o repositório

spa_angular_typescript_hello-world
, torne ele o seu diretório atual:

cd spa_angular_typescript_hello-world

Instale as dependências do projeto Angular da seguinte forma:

npm install

Este projeto Angular inicial oferece uma aplicação funcional que consome dados de uma API externa para hidratar a interface do usuário. Para simplicidade e conveniência, o projeto inicial simula a API externa localmente usando

json-server
. Posteriormente, você integrará esta aplicação Angular com um servidor de API real usando uma tecnologia de back-end de sua escolha.

O servidor de API compatível é executado em

http://localhost:6060
por padrão. Dessa forma, para conectar sua aplicação Angular com esse servidor de API, crie um arquivo
.env
no diretório raiz do projeto:

touch .env

Preencha o arquivo

.env
com as seguintes variáveis de ambiente:

API_SERVER_URL=http://localhost:6060

Este projeto usa um script npm para integrar o conteúdo do arquivo

.env
com o framework Angular. Confira o arquivo
set-env.ts
:

const { writeFile } = require('fs');
const { promisify } = require('util');
const dotenv = require('dotenv');

dotenv.config();

const writeFilePromisified = promisify(writeFile);

const targetPath = './src/environments/environment.ts';

const envConfigFile = `export const environment = {
 production: false,
 api: {
   serverUrl: '${process.env['API_SERVER_URL']}',
 },
};
`;

(async () => {
  try {
    await writeFilePromisified(targetPath, envConfigFile);
  } catch (err) {
    console.error(err);
    throw err;
  }
})();

Este script usa o pacote

dotenv
para carregar variáveis de ambiente de um arquivo
.env
para
process.env
. O script então usa um modelo de string para criar o conteúdo do arquivo
./src/environments/environment.ts
. Em seguida, ele grava esse arquivo com o conteúdo prescrito no projeto Angular.

O script npm

env
definido em
package.json
executa o script
set-env.ts
usando
ts-node
. No entanto, você não precisa executar o comando
npm run env
diretamente. O script npm
start
executará isso para você antes de iniciar o servidor de desenvolvimento Angular.

Assim, execute o seguinte comando para executar a aplicação Angular:

npm start

Em seguida, execute o seguinte comando para executar a API do servidor JSON:

npm run api

Tudo pronto para você começar a implementar a autenticação do usuário neste projeto Angular. Primeiro, você precisará configurar a aplicação Angular para se conectar com sucesso à Auth0. Posteriormente, você usará o SDK da Auth0 para Angular para proteger rotas, exibir informações de perfil do usuário e solicitar dados protegidos de um servidor de API externo para hidratar algumas das páginas da aplicação.

Configure o Angular com a Auth0

Siga as etapas para começar a usar a plataforma de identidade Auth0 rapidamente:

Se inscreva e crie uma Aplicação Auth0

Autenticação para pessoas desenvolvedoras

Obtenha a Auth0 gratuitamente com até 7.000 usuários ativos e logins ilimitados. Não é necessário cartão de crédito. Crie uma conta Auth0 gratuita. and more text.

Uma conta gratuita oferece:

Durante o cadastro, você cria um Auth0 Tenant, que representa o produto ou serviço ao qual você está adicionando autenticação.

Depois de se inscrever, Auth0 leva você para o Dashboard. No menu da barra lateral esquerda, clique em "Applications".

Em seguida, clique no botão "Create Application". Irá abrir um formulário para que você escreva o nome da aplicação e escolha seu o tipo. Use os seguintes valores:

Nome:

Auth0 Angular Code Sample

Application Type (Tipo da aplicação):

Auth0 React Code Sample

Application Type (Tipo da aplicação):

Single Page Web Applications

Clique no botão "Create" para concluir o processo. A página da sua aplicação Auth0 será carregada.

Na próxima etapa, você aprenderá como ajudar o Angular e a Auth0 a se comunicarem.

Qual é a relação entre Auth0 Tenants e aplicações Auth0?

Digamos que você tenha uma aplicação Angular de compartilhamento de fotos chamado “NG-Gram”. Você então criaria um Auth0 tenant chamado

ng-gram
. Do ponto de vista do cliente, NG-Gram é o produto ou serviço desse cliente.

Agora, digamos que o NG-Gram esteja disponível em três plataformas: na web como uma aplicação de página única (Single Page Application ou SPA em inglês) e como um aplicativo móvel nativo para Android e iOS. Se cada plataforma precisar de autenticação, você precisará criar três aplicações Auth0 para fornecer ao produto tudo o que a pessoa precisa para autenticar os usuários por meio dessa plataforma.

Os usuários do NG-Gram pertencem ao tenant NG-Gram, que os compartilha em suas aplicações Auth0.

Crie uma ponte de comunicação entre o Angular e Auth0

Ao usar a plataforma de identidade Auth0, você não precisa criar formulários de login. A Auth0 oferece uma página de Login universal para reduzir a sobrecarga de adição e gerenciamento de autenticação.

Como o Login Universal funciona?

Sua aplicação Angular redirecionará os usuários para a Auth0 sempre que eles dispararem uma requisição de autenticação. A Auth0 irá apresentar uma página de login. Assim que eles fizerem login, a Auth0 os redirecionará de volta para a sua aplicação Angular. Para que o redirecionamento ocorra com segurança, você deve especificar nas suas configurações de aplicações Auth0 as URLs para os quais a Auth0 pode redirecionar usuários, uma vez que estejam autenticados.

Clique na guia "Settings" da página da aplicação Auth0, localize a seção “Application URIs” e preencha os seguintes valores:

URLs de callback permitidas (Allowed Callback URLs em inglês)

http://localhost:4040/callback

O valor acima é a URL que Auth0 pode usar para redirecionar seus usuários depois que fizerem login.

URLs de logout permitidas (Allowed Logout URLs em inglês)

http://localhost:4040

O valor acima é a URL que Auth0 pode usar para redirecionar seus usuários depois que fizerem logout.

Origens Web permitidas (Allowed Web Origins em inglês)

http://localhost:4040

Usando o SDK da Auth0 para Angular, sua aplicação Angular fará requisições internas a uma URL da Auth0 para lidar com as requisições de autenticação. Você precisa adicionar a URL de origem da aplicação React para evitar problemas de Compartilhamento de recursos de origem cruzada (Cross-Origin Resource Sharing (CORS)).

Role para baixo e clique no botão "Save changes".

Não feche esta página ainda. Você precisará de algumas informações na próxima seção.

Adicione as variáveis de configuração da Auth0 ao Angular

Na aba "Settings" da página da aplicação Auth0, você precisa dos valores de Domínio Auth0 (Auth0 Domain em inglês) e ID do Cliente (Client ID em inglês) para permitir que sua aplicação Angular use a ponte de comunicação que você criou.

O que exatamente é um domínio Auth0 e um ID de cliente Auth0?

Domínio

Quando você criou uma nova conta Auth0, a Auth0 pediu para escolher um nome para seu tenant. Este nome, anexado com

auth0.com
, é o seu domínio Auth0 (Auth0 Domain em inglês). É a URL base que você irá usar para acessar as APIs Auth0 e a URL que você vai redirecionar os usuários para fazer login:

Auth0 também oferece suporte a domínios personalizados para permitir que a Auth0 faça o trabalho pesado de autenticação para você sem comprometer sua experiência de branding.

ID do Cliente

A Auth0 atribui um ID de cliente (Client ID) a cada aplicação quando criada, que é uma string alfanumérica, e é o identificador exclusivo da sua aplicação (como

q8fij2iug0CmgPLfTfG1tZGdTQyGaTUA
). Você não pode modificar o ID do cliente. Você usará o ID do cliente para identificar a aplicação Auth0 que o SDK da Auth0 para Single Page Application (SPA) precisa se conectar.

Atenção: Outra informação crítica presente nas "Settings" é o Segredo do Cliente (Client Secret em inglês). Esse segredo protege seus recursos concedendo tokens apenas para solicitantes se estiverem autorizados. Pense nisso como a senha da sua aplicação, que deve ser mantida em sigilo o tempo todo. Se alguém obtiver acesso ao seu Client Secret, poderá se passar pela sua aplicação e acessar recursos protegidos.

Volte para a página da aplicação Auth0 e clique na guia "Settings".

Localize a seção "Basic Information" e siga estas etapas para obter os valores de Auth0 Domain e Auth0 Client ID:

Configurações da aplicação Auth0 para habilitar autenticação de usuário

"Domain" e "Client ID" permitem que sua aplicação Angular se identifique como uma parte autorizada para interagir com o servidor de autenticação Auth0. Agora, atualize o arquivo

.env
no diretório do projeto Angular da seguinte forma:

API_SERVER_URL=http://localhost:6060
AUTH0_DOMAIN=<AUTH0-DOMAIN>
AUTH0_CLIENT_ID=<AUTH0-CLIENT-ID>
AUTH0_CALLBACK_URL=http://localhost:4040/callback

Lembre-se de preencher os valores para as variáveis

AUTH0_DOMAIN
e
AUTH0_CLIENT_ID
com as informações obtidas na página da sua aplicação no dashboard da Auth0.

Depois de chegar à seção "Chamar uma API protegida a partir do Angular" deste guia, você aprenderá como usar

API_SERVER_URL
junto com um valor Auth0 Audience para solicitar recursos protegidos de uma API externa que também é protegida por Auth0. Por enquanto, a aplicação está usando
json-server
para simular a API.

Atualize o arquivo de script

set-env.ts
para integrar essas novas variáveis de ambiente Auth0 de
.env
em seu arquivo Angular
rc/environments/environment.ts
:

const { writeFile } = require('fs');
const { promisify } = require('util');
const dotenv = require('dotenv');

dotenv.config();

const writeFilePromisified = promisify(writeFile);

const targetPath = './src/environments/environment.ts';

const envConfigFile = `export const environment = {
 production: false,
 auth0: {
   domain: '${process.env['AUTH0_DOMAIN']}',
   clientId: '${process.env['AUTH0_CLIENT_ID']}',
   authorizationParams: {
     redirect_uri: '${process.env['AUTH0_CALLBACK_URL']}',
   },
 },
 api: {
   serverUrl: '${process.env['API_SERVER_URL']}',
 },
};
`;

(async () => {
  try {
    await writeFilePromisified(targetPath, envConfigFile);
  } catch (err) {
    console.error(err);
    throw err;
  }
})();

Você está criando um objeto

auth0
usando os valores de configuração da aplicação Auth0 criado no Dashboard Auth0: Auth0 Domain e Client ID.

Além disso, você usa o objeto de configuração

authorizationParams
para definir os parâmetros de consulta que o Angular precisa incluir em suas chamadas para o endpoint
/authorize
da Auth0. Você define a propriedade
redirect_uri
dentro deste objeto para especificar a URL da sua aplicação Angular para onde a Auth0 deve redirecionar seus usuários após efetuarem login com sucesso.

Posteriormente, você usará as propriedades do objeto

auth0
para configurar o
AuthModule
do SDK da Auth0 para Angular usando o
padrão forRoot()
.

Reinicie seu servidor de desenvolvimento Angular para gerar novamente o arquivo

src/environments/environment.ts
:

npm start

Lide com o comportamento pós-login Auth0

Observe que a URL de retorno de chamada Auth0,

AUTH0_CALLBACK_URL
, aponta para
http://localhost:4040/callback
que é a URL que Auth0 usa para redirecionar seus usuários após eles efetuarem login com sucesso. Para esta aplicação Angular, você vai renderizar um componente de uma página simples para a rota
/callback
.

Você usará o Angular CLI para gerar e modificar arquivos. Você pode instalá-lo usando npm seguindo as instruções na documentação oficial.

Comece criando um arquivo

CallbackModule
no diretório
src/app/features
usando o Angular CLI:

ng g module features/callback --routing

Em seguida, use a CLI Angular para criar um

CallbackComponent
no diretório
src/app/features/callback
e declare-o no
CallbackModule
:

ng g component features/callback --module=features/callback/callback.module.ts --skip-tests --style=none

Atualize o

CallbackModule
para incluir o
SharedModule
em seu array
imports
:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@app/shared';
import { CallbackComponent } from './callback.component';
import { CallbackRoutingModule } from './callback-routing.module';

@NgModule({
  declarations: [CallbackComponent],
  imports: [CommonModule, SharedModule, CallbackRoutingModule],
})
export class CallbackModule {}

Atualize o

CallbackRoutingModule
para definir
CallbackComponent
como a rota padrão:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CallbackComponent } from './callback.component';

const routes: Routes = [
  {
    path: '',
    component: CallbackComponent,
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class CallbackRoutingModule {}

Preencha o arquivo de template

src/app/features/callback/callback.component.html
da seguinte maneira:

<div class="page-layout">
  <app-nav-bar></app-nav-bar>
  <app-mobile-nav-bar></app-mobile-nav-bar>
  <div class="page-layout__content">
    <ng-content></ng-content>
  </div>
</div>

O componente

CallbackComponent
renderizará apenas a barra de navegação e um contêiner de conteúdo vazio para te ajudar a criar uma transição suave entre uma rota sem conteúdo,
/callback
, para uma rota com conteúdo, como a página
/profile
.

A próxima etapa é carregar o

CallbackModule
usando o roteador Angular.

Localize o arquivo

src/app/app-routing.module.ts
e atualize-o da seguinte forma:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    loadChildren: () =>
      import('./features/home/home.module').then((m) => m.HomeModule),
  },
  {
    path: 'profile',
    loadChildren: () =>
      import('./features/profile/profile.module').then((m) => m.ProfileModule),
  },
  {
    path: 'public',
    loadChildren: () =>
      import('./features/public/public.module').then((m) => m.PublicModule),
  },
  {
    path: 'protected',
    loadChildren: () =>
      import('./features/protected/protected.module').then(
        (m) => m.ProtectedModule,
      ),
  },
  {
    path: 'admin',
    loadChildren: () =>
      import('./features/admin/admin.module').then((m) => m.AdminModule),
  },
  {
    path: 'callback',
    loadChildren: () =>
      import('./features/callback/callback.module').then(
        (m) => m.CallbackModule,
      ),
  },
  {
    path: '**',
    loadChildren: () =>
      import('./features/not-found/not-found.module').then(
        (m) => m.NotFoundModule,
      ),
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
Quais são os benefícios de usar uma página de callback?

A implementação de uma página especializada em lidar com o redirecionamento do usuário da página de login universal da Auth0 para sua aplicação (o evento callback) traz alguns benefícios:

  • Seus usuários não verão nenhum componente piscando na página inicial, que é renderizado no caminho raiz,
    /
    .
  • Ao mostrar a barra de navegação na rota
    /callback
    , seu usuário pode sentir que sua aplicação Angular carrega rápido.
  • Ao não mostrar o rodapé, seus usuários podem achar que sua aplicação Angular carrega sem problemas.
  • Você pode evitar chamadas de API desnecessárias ou custosas que podem ser executadas ao carregar os componentes da página inicial.

Depois de adicionar um botão de login e logout nesta aplicação, você pode verificar essa melhoria na experiência de usuário usando as ferramentas de desenvolvedor do seu navegador. No caso do Google Chrome, você pode fazer o seguinte:

Se você ainda não se convenceu, vamos explorar mais detalhes sobre o impacto dessa estratégia.

Imagine que você deseja redirecionar seus usuários para o

/profile
depois que eles fizerem login. Se você fosse usar a URL raiz da sua aplicação Angular,
http://localhost:4040
, como a Auth0 Callback URL, você pode prejudicar a experiência do usuário quando a conexão do usuário é lenta ou quando a rota
/profile
é carregada lentamente:

  • Esta aplicação Angular oferece uma página
    /profile
    que exibirá informações de perfil do usuário, como nome e endereço de e-mail. No entanto, essa aplicação também carrega lentamente a rota
    /profile
    usando o Angular Router.
  • Como as informações do perfil do usuário são privadas, elas devem ser protegidas contra acesso não autorizado.
  • O SDK da Auth0 para Angular permite que você exija facilmente que os usuários façam login antes de poder acessar uma rota.
  • Quando um usuário que não está logado clica na aba de navegação da página
    /profile
    , a Auth0 irá direcioná-lo para uma página de login.
  • Depois que seus usuários fizerem login, a Auth0 os redirecionará de volta para sua aplicação Angular com alguns metadados que permitem que sua aplicação os redirecione para a página protegida que eles pretendem acessar.
  • Quando você usa
    http://localhost:4040
    como a Auth0 Callback URL, a Auth0 redirecionará seus usuários para a página inicial primeiro. Dependendo da rapidez com que sua aplicação renderiza páginas e lida com redirecionamentos, seus usuários podem ver a página inicial antes que o Angular os leve para a página
    /profile
    quando a conexão estiver lenta ou quando você estiver carregando lentamente essa rota. Esse rápido reencaminhamento faz a interface do usuário "piscar", dando a impressão que a interface do usuário é irregular ou apresenta falhas.
  • No entanto, quando você usa
    http://localhost:4040/callback
    como Auth0 Callback URL, a Auth0 levará seus usuários a uma rota
    /callback
    após o login. Você pode exibir uma animação de carregamento ou nada nessa rota especial. Isso torna a transição de
    /callback
    para
    /profile
    mais suave, pois nenhum conteúdo não relacionado ou inesperado aparece no processo.

Além disso, ao carregar a página inicial,

/
, você pode acionar a lógica que busca dados de uma API externa ou executa qualquer outra lógica de negócios relacionada à hidratação da página inicial. Se sua intenção é mostrar aos usuários uma página
/profile
após eles efetuarem login, não há necessidade ou valor em executar qualquer lógica de negócios da página inicial que não afete a renderização da página
/profile
. Em vez disso, você pode aumentar seus custos operacionais executando lógica desnecessária quando qualquer um de seus usuários fizer login. Nesse caso, é melhor lidar com o redirecionamento Auth0 em uma rota especializada mínima e de alto desempenho,
/callback
.

Instale E Configure O SDK Da Auth0 Para Angular

Execute o seguinte comando para instalar o SDK da Auth0 para Angular:

npm install --save @auth0/auth0-angular

O SDK da Auth0 para Angular expõe vários métodos, variáveis e tipos que ajudam a integrar o Auth0 com sua aplicação Angular de forma idiomática, incluindo um módulo e serviço de autenticação.

Atualize o arquivo

src/app/app.module.ts
da seguinte forma para importar o
AuthModule
do SDK da Auth0 para Angular para o seu
AppModule
e configure-o usando os dados do seu módulo
environment
:

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AuthModule } from '@auth0/auth0-angular';
import { environment as env } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    AuthModule.forRoot({
      ...env.auth0,
    }),
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Você usa o

padrão forRoot()
para configurar o
AuthModule
, que usa um objeto com as propriedades
domain
,
clientId
, e
authorizationParams
. Você cria esse objeto de configuração espalhando o objeto
env.auth
.

A autenticação do usuário é um mecanismo para controlar quem pode acessar sua aplicação. Você pode integrar sua aplicação com a Auth0 para impedir que usuários que não efetuaram login acessem uma rota

/profile
ou
/admin
.

Se os usuários quiserem acessar uma rota protegida da sua aplicação, a Auth0 os interromperá e solicitará que apresentem suas credenciais. Se a Auth0 puder verificar quem eles são e se eles devem entrar lá, a Auth0 os deixará entrar.

O processo de autenticação não acontecerá dentro da sua camada de aplicação Angular ao usar a Auth0. Sua aplicação Angular redirecionará seus usuários para a página de Login Universal Auth0, onde a Auth0 solicitará credenciais e redirecionará o usuário de volta para sua aplicação com o resultado do processo de autenticação.

Conexão Auth0 e Angular

Você concluiu a configuração de um serviço de autenticação que sua aplicação Angular pode consumir. Continue construindo o projeto inicial ao longo deste guia, implementando componentes Angular para acionar e gerenciar o fluxo de autenticação.

Fique à vontade para se aprofundar na documentação da Auth0 para saber mais sobre como a Auth0 ajuda a economizar tempo na implementação e gerenciamento de identidade.

Adicione Login De Usuário Para Angular

As etapas de como construir um formulário de login Angular ou página de login são complexas. Você pode economizar tempo de desenvolvimento usando uma página de login hospedada pela Auth0 que possui um formulário de login integrado que oferece suporte a diferentes tipos de autenticação de usuário: nome de usuário e senha, login social e autenticação multifator (MFA). Você só precisa criar um botão que leve as pessoas usuárias da sua aplicação Angular para a página de login.

Comece gerando um arquivo

LoginButtonComponent
no diretório
src/app/shared/components/buttons
e registre-o no
SharedModule
usando o Angular CLI:

ng g component shared/components/buttons/login-button --module=shared/shared.module.ts --inline-template --skip-tests --style=none --flat --export

Preencha

src/app/shared/components/buttons/login-button.component.ts
assim:

import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';

@Component({
 selector: 'app-login-button',
 template: `
   <button class="button__login" (click)="handleLogin()">Log In</button>
 `,
})
export class LoginButtonComponent {
 constructor(private auth: AuthService) {}

 handleLogin(): void {
   this.auth.loginWithRedirect({
     appState: {
       target: '/profile',
     },
   });
 }
}

Dentro da definição de

LoginButtonComponent
,
this.auth.loginWithRedirect()
é um método exposto por
AuthService
que executa um redirecionamento para o endpoint Auth0
/authorize
para iniciar o processo de autenticação. Você pode passar um objeto de configuração para esse método para personalizar a experiência de login.

Ao configurar o valor de

appState.target
para
/profile
, você está informando ao SDK da Auth0 para Angular o seguinte: Quando meus usuários fizerem login com a Auth0 e retornarem à minha aplicação Angular, leve-os do caminho da URL de callback padrão,
/callback
, para a página "Profile",
/profile
. Se você não especificar esta opção
appState.returnTo
, seus usuários serão redirecionados por padrão para o caminho
/
após efetuarem login.

Na próxima seção, você vai configurar esse método para criar um botão no qual seus usuários podem clicar para se inscrever na sua aplicação.

Adicione Inscrição De Usuário Ao Angular

O processo de como construir um formulário de inscrição Angular é muito mais complexo. No entanto, você pode usar um formulário de inscrição hospedado pela Auth0 que possui uma verificação de força de senha integrada.

Você pode criar um botão que leve os usuários da sua aplicação Angular para a página de inscrição adicionando a propriedade

screen_hint=signup
ao objeto de configuração
authorizationParams
do método
loginWithRedirect()
:

authorizationParams: {
 screen_hint: "signup",
}

Este método

loginWithRedirect()
é um wrapper do método Auth0 SPA SDK com o mesmo nome. Dessa forma, você pode usar o documento
RedirectLoginOptions
do Auth0 SPA SDK para saber mais detalhes sobre essas opções de configuração.

Para ver isso na prática, gere um arquivo

SignupButtonComponent
no diretório
src/app/shared/components/buttons
e registre-o no
SharedModule
usando o Angular CLI:

ng g component shared/components/buttons/signup-button --module=shared/shared.module.ts --inline-template --skip-tests --style=none --flat --export

Preencha

src/app/shared/components/buttons/signup-button.component.ts
com o conteúdo abaixo para definir um componente de botão de inscrição:

import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';

@Component({
 selector: 'app-signup-button',
 template: `
   <button class="button__sign-up" (click)="handleSignUp()">Sign Up</button>
 `,
})
export class SignupButtonComponent {
 constructor(private auth: AuthService) {}

 handleSignUp(): void {
   this.auth.loginWithRedirect({
     appState: {
       target: '/profile',
     },
     authorizationParams: {
       screen_hint: 'signup',
     },
   });
 }
}

O uso do recurso de inscrição Auth0 exige que você ative o Auth0 New Universal Login Experience em seu tenant.

Abra a seção Login Universal do dashboard Auth0 e escolha a opção "New" na subseção "Experience".

Opções da Auth0 Universal Login Experience

Role para baixo e clique no botão "Save Changes".

A diferença entre a experiência de usuário em login e inscrição ficará mais evidente quando você integrar esses componentes à aplicação Angular e vê-los em ação. Você fará isso nas próximas seções.

Adicione Logout De Usuário Para O Angular

Você pode desconectar usuários de sua aplicação Angular efetuando o logout de suas sessões Auth0 usando o método

logout()
do SDK da Auth0 para Angular.

Gere um arquivo

LogoutButtonComponent
no diretório
src/app/shared/components/buttons
e registre-o no
SharedModule
usando o Angular CLI:

ng g component shared/components/buttons/logout-button --module=shared/shared.module.ts --inline-template --skip-tests --style=none --flat --export

Preencha

src/app/shared/components/buttons/logout-button.component.ts
assim:

import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { AuthService } from '@auth0/auth0-angular';

@Component({
 selector: 'app-logout-button',
 template: `
   <button class="button__logout" (click)="handleLogout()">Log Out</button>
 `,
})
export class LogoutButtonComponent {
 constructor(
   private auth: AuthService,
   @Inject(DOCUMENT) private doc: Document
 ) {}

 handleLogout(): void {
   this.auth.logout({
     logoutParams: {
       returnTo: this.doc.location.origin,
     },
   });
 }
}

Ao usar o método

logout()
, o SDK da Auth0 para Angular limpa a sessão da aplicação e redireciona para o endpoint Auth0
/v2/logout
para limpar a sessão Auth0 por baixo dos panos.

Assim como nos métodos de login, você pode passar um argumento de objeto para

logout()
para customizar o comportamento ao desconectar o usuário na aplicação Angular. Você pode definir a propriedade
logoutParams
no objeto de configuração para definir parâmetros da chamada
/v2/logout
. Este processo é bastante invisível para o usuário. Consulte
LogoutParams
(em inglês) para obter mais detalhes sobre os parâmetros disponíveis.

Aqui, você passa a opção

logoutParams.returnTo
para especificar a URL onde a Auth0 deve redirecionar seus usuários após o logout. No momento, você está trabalhando localmente e as "Allowed Logout URLs" da sua aplicação Auth0 apontam para
http://localhost:4040
.

No entanto, se você fosse fazer o deploy da sua aplicação Angular para produção, você precisa adicionar a URL de saída de produção à lista "Allowed Logout URLs" e garantir que a Auth0 redirecione seus usuários para essa URL de produção e não

localhost
. Definir
logoutParams.returnTo
como
window.location.origin
fará exatamente isso.

Uma prática recomendada ao trabalhar com Auth0 é ter tenants diferentes para seus diferentes ambientes de projeto. Por exemplo, é recomendável que pessoas desenvolvedoras especifiquem um tenant de produção. Um tenant de produção obtém limites de taxa mais altos do que os tenants que não são de produção. Confira o documento Auth0 "Configurar vários ambientes" (em inglês) para saber mais sobre como configurar ambientes de desenvolvimento, staging e produção na plataforma de identidade Auth0.

Renderize Componentes Condicionalmente

Nesta seção, você aprenderá como renderizar componentes React condicionalmente com base no status do SDK da Auth0 para Angular ou no status de autenticação de seus usuários.

Renderize os botões de autenticação condicionalmente

A aplicação inicial Angular apresenta uma experiência de navegação em desktop e móvel.

Ao usar sua aplicação Angular em uma viewport grande o suficiente para corrigir uma experiência de desktop ou tablet, você verá uma barra de navegação na parte superior da página.

Ao usar uma viewport que se ajusta às restrições de tela de um dispositivo móvel, você verá um botão de menu no canto superior direito da página. Tocar ou clicar no botão de menu abre um modal que mostra as diferentes páginas que você pode acessar na aplicação.

Nesta seção, você irá expor os componentes do botão que acionam os eventos de login, inscrição e logout por meio desses elementos de navegação da página.

Vamos começar com a experiência do usuário de navegação na área de trabalho. Você mostrará os botões de login e inscrição na barra de navegação quando o usuário não estiver logado. Naturalmente, você mostrará o botão de logout quando o usuário estiver logado.

Crie uma variável

isAuthenticated$
no
NavBarButtonsComponent
para implementar a experiência do usuário definida acima:

import { Component } from '@angular/core';
import { AuthService } from "@auth0/auth0-angular";

@Component({
 selector: 'app-nav-bar-buttons',
 templateUrl: './nav-bar-buttons.component.html',
})
export class NavBarButtonsComponent {

 isAuthenticated$ = this.authService.isAuthenticated$
 constructor(private authService: AuthService) {}
}

Em seguida, atualize

src/app/shared/components/navigation/desktop/nav-bar-buttons.component.html
da seguinte maneira para mostrar e ocultar condicionalmente os botões de login, inscrição e logout:

<div class="nav-bar__buttons">
  <ng-container *ngIf="isAuthenticated$ | async; else unAuthenticated">
    <app-logout-button></app-logout-button>
  </ng-container>
  <ng-template #unAuthenticated>
    <app-signup-button></app-signup-button>
    <app-login-button></app-login-button>
  </ng-template>
</div>

O valor

isAuthenticated$
reflete o estado de autenticação de seus usuários conforme rastreado pelo SDK da Auth0 para Angular. Esse valor é
true
quando o usuário foi autenticado e
false
caso contrário. Dessa forma, você pode usar o valor
isAuthenticated$
para renderizar elementos de IU condicionalmente, dependendo do estado de autenticação de seus usuários, como você fez acima.

A experiência de navegação móvel funciona da mesma maneira, exceto que os botões relacionados à autenticação estão inseridos no modal do menu móvel.

Atualize

src/app/shared/components/navigation/mobile/mobile-nav-bar-buttons.component.ts
assim:

import { Component } from '@angular/core';
import { AuthService } from "@auth0/auth0-angular";

@Component({
 selector: 'app-mobile-nav-bar-buttons',
 templateUrl: './mobile-nav-bar-buttons.component.html',
})
export class MobileNavBarButtonsComponent {

 isAuthenticated$ = this.authService.isAuthenticated$
 constructor(private authService: AuthService) {}
}

Em seguida, atualize

src/app/shared/components/navigation/mobile/mobile-nav-bar-buttons.component.html
da seguinte maneira para mostrar e ocultar condicionalmente os botões de login, inscrição e logout:

<div class="mobile-nav-bar__buttons">
  <ng-container *ngIf="isAuthenticated$ | async; else unAuthenticated">
    <app-logout-button></app-logout-button>
  </ng-container>
  <ng-template #unAuthenticated>
    <app-signup-button></app-signup-button>
    <app-login-button></app-login-button>
  </ng-template>
</div>

Vá em frente e tente fazer o login. Sua aplicação Angular redireciona você para a página de login universal da Auth0. Você pode usar um formulário para fazer login com um nome de usuário e senha ou um provedor de identidade social como o Google. Observe que esta página de login também oferece a opção de se inscrever.

Formulário da nova experiência do Login Universal Auth0

No entanto, quando você clica no botão de inscrição diretamente em sua aplicação, o Angular leva você para a página de inscrição, onde seus usuários podem se inscrever na aplicação Angular. Experimente!

Nova página de inscrição na Experiência de Login Universal Auth0

Você pode personalizar a aparência das novas páginas de Login Universal. Você também pode substituir qualquer texto na "New Experience" usando a API de Personalização de Texto.

Observe que, quando você termina de fazer login ou de se inscrever, a Auth0 redireciona você para sua aplicação Angular, mas os botões de login e inscrição podem aparecer brevemente antes do botão de logout renderizar. Você vai consertar isso já já.

Renderize a aplicação condicionalmente

A interface do usuário "pisca" porque sua aplicação Angular não sabe se a Auth0 já autenticou o usuário. Sua aplicação saberá o status de autenticação do usuário depois que o SDK da Auth0 para Angular for carregado.

Para corrigir a intermitência da interface de usuário (UI), use o valor do observable

isLoading$
exposto por
AuthService
que emite um valor booleano para renderizar o componente
AppComponent
assim que o SDK da Auth0 para Angular terminar de carregar.

Comece importando

SharedModule
para
AppModule
:

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AuthModule } from '@auth0/auth0-angular';
import { environment as env } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SharedModule } from './shared';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    SharedModule,
    AuthModule.forRoot({
      ...env.auth0,
    }),
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Em seguida, abra

src/app/app.component.ts
e atribua o observable
isLoading$
da Auth0 a uma variável:

import { Component } from '@angular/core';
import { AuthService } from "@auth0/auth0-angular";

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
})
export class AppComponent {

 isAuth0Loading$ = this.authService.isLoading$;
 constructor(private authService: AuthService) {}
}

Abra o arquivo

src/app/app.component.html
e o atualize assim:

<div class="page-layout" *ngIf="isAuth0Loading$ | async; else auth0Loaded">
  <app-page-loader></app-page-loader>
</div>
<ng-template #auth0Loaded>
  <router-outlet></router-outlet>
</ng-template>

Enquanto o SDK está carregando, o componente

PageLoaderComponent
é renderizado, o que mostra uma animação. Faça logout e login novamente para ver isso em ação. A “piscada” na interface do usuário não deve mais acontecer.

Renderize guias de navegação condicionalmente

Pode haver casos de uso em que você deseja ocultar elementos da interface do usuário para aqueles usuários que não efetuaram login em sua aplicação. Para esta aplicação inicial, apenas usuários autenticados devem ver as guias de navegação para acessar as páginas

/protected
e
/admin
.

Para implementar esse caso de uso, você contará novamente com o valor

isAuthenticated$
do observable
AuthService
.

Abra o arquivo do componente

src/app/shared/components/navigation/desktop/nav-bar-tabs.component.ts
que define as guias de navegação da área de trabalho e atualize-o da seguinte forma:

import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';

@Component({
 selector: 'app-nav-bar-tabs',
 templateUrl: './nav-bar-tabs.component.html',
})
export class NavBarTabsComponent {

 isAuthenticated$ = this.authService.isAuthenticated$;
 constructor(private authService: AuthService) {}
}

Abra o arquivo de componente

src/app/shared/components/navigation/desktop/nav-bar-tabs.component.html
e atualize-o da seguinte forma:

<div class="nav-bar__tabs">
  <app-nav-bar-tab path="/profile" label="Profile"></app-nav-bar-tab>
  <app-nav-bar-tab path="/public" label="Public"></app-nav-bar-tab>
  <ng-container *ngIf="isAuthenticated$ | async">
    <app-nav-bar-tab path="/protected" label="Protected"></app-nav-bar-tab>
    <app-nav-bar-tab path="/admin" label="Admin"></app-nav-bar-tab>
  </ng-container>
</div>

Em seguida, abra o arquivo do componente

src/app/shared/components/navigation/mobile/mobile-nav-bar-tabs.component.ts
que define suas guias de navegação móvel e atualize-o da seguinte forma:

import { Component, EventEmitter, Output } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';

@Component({
 selector: 'app-mobile-nav-bar-tabs',
 templateUrl: './mobile-nav-bar-tabs.component.html',
})
export class MobileNavBarTabsComponent {
 @Output() mobileNavBarTabClick = new EventEmitter<string>();

 isAuthenticated$ = this.auth.isAuthenticated$;

 constructor(private auth: AuthService) {}

 onMobileNavBarTabClick(path: string): void {
   this.mobileNavBarTabClick.emit(path);
 }
}

Abra o arquivo de componente

src/app/shared/components/navigation/mobile/nav-bar-tabs.component.html
e atualize-o da seguinte forma:

<div class="mobile-nav-bar__tabs">
  <app-mobile-nav-bar-tab
    path="/profile"
    label="Profile"
    (mobileNavBarTabClick)="onMobileNavBarTabClick($event)"
  ></app-mobile-nav-bar-tab>
  <app-mobile-nav-bar-tab
    path="/public"
    label="Public"
    (mobileNavBarTabClick)="onMobileNavBarTabClick($event)"
  ></app-mobile-nav-bar-tab>
  <ng-container *ngIf="isAuthenticated$ | async">
    <app-mobile-nav-bar-tab
      path="/protected"
      label="Protected"
      (mobileNavBarTabClick)="onMobileNavBarTabClick($event)"
    ></app-mobile-nav-bar-tab>
    <app-mobile-nav-bar-tab
      path="/admin"
      label="Admin"
      (mobileNavBarTabClick)="onMobileNavBarTabClick($event)"
    ></app-mobile-nav-bar-tab>
  </ng-container>
</div>

Saia de sua aplicação Angular e observe como agora você só pode ver as guias das páginas

/profile
e
/public
na barra de navegação, juntamente com os botões de login e inscrição. Faça o login e veja o resto da barra de navegação aparecer.

Lembre-se de que isso não restringe o acesso às páginas

/admin
e
/protected
. Você aprenderá como usar o SDK da Auth0 para Angular para proteger rotas Angular na próxima seção.

Adicione Guardas De Rota Ao Angular

Você pode criar um guarda de rota de autenticação para proteger as rotas Angular. O Angular solicitará aos usuários que visitam a rota que façam login, caso ainda não o tenham feito. Depois de fazer login, o Angular os leva para a rota que eles tentaram acessar.

Você pode aplicar um guarda a qualquer rota definida no módulo roteador Angular atualizando

src/app/app-routing.module.ts
da seguinte forma:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@auth0/auth0-angular';

const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    loadChildren: () =>
      import('./features/home/home.module').then((m) => m.HomeModule),
  },
  {
    path: 'profile',
    loadChildren: () =>
      import('./features/profile/profile.module').then((m) => m.ProfileModule),
    canActivate: [AuthGuard],
  },
  {
    path: 'public',
    loadChildren: () =>
      import('./features/public/public.module').then((m) => m.PublicModule),
  },
  {
    path: 'protected',
    loadChildren: () =>
      import('./features/protected/protected.module').then(
        (m) => m.ProtectedModule,
      ),
    canActivate: [AuthGuard],
  },
  {
    path: 'admin',
    loadChildren: () =>
      import('./features/admin/admin.module').then((m) => m.AdminModule),
    canActivate: [AuthGuard],
  },
  {
    path: 'callback',
    loadChildren: () =>
      import('./features/callback/callback.module').then(
        (m) => m.CallbackModule,
      ),
  },
  {
    path: '**',
    loadChildren: () =>
      import('./features/not-found/not-found.module').then(
        (m) => m.NotFoundModule,
      ),
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Você usa o

AuthGuard
do SDK da Auth0 para Angular para proteger as rotas
/profile
,
/protected
e
/admin
adicionando-as ao valor da propriedade de configuração de rotas
canActivate
.

Se as condições definidas pelo

AuthGuard
passarem, o componente será renderizado. Caso contrário, o
AuthGuard
instrui o Angular a te levar para a página de login universal Auth0 para autenticação.

Agora você pode testar se esses caminhos protegidos exigem que os usuários façam login antes de acessá-los. Faça logout e tente acessar as páginas Profile, Protected ou Admin. Se funcionar, o Angular redireciona você para fazer login com Auth0.

Depois de fazer login, o React deve levá-lo à página

/profile
conforme especificado pela propriedade
appState.target
presente na definição do componente do botão de login.

Os protetores do lado do cliente melhoram a experiência do usuário em sua aplicação Angular, não sua segurança.

No Security StackExchange, Conor Mancone explica que as proteções do lado do servidor visam proteger os dados, enquanto as proteções do lado do cliente visam melhorar a experiência do usuário.

As principais conclusões de sua resposta são:

  • Você não pode confiar em restrições do lado do cliente, como protetores de navegação e rotas protegidas, para proteger informações confidenciais.
  • Os invasores podem eventualmente contornar as restrições do lado do cliente.
  • Seu servidor não deve retornar nenhum dado que um usuário não deva acessar. A abordagem errada é retornar todos os dados do usuário do servidor e deixar o framework de front-end decidir o que exibir e o que ocultar com base no status de autenticação do usuário.
  • Qualquer pessoa pode abrir as ferramentas para pessoas desenvolvedoras do navegador e inspecionar as solicitações de rede para visualizar todos os dados.
  • O uso de guardas de navegação ajuda a melhorar a experiência do usuário, não a segurança do usuário. _ Sem guardas, um usuário que não fez login pode entrar em uma página com informações restritas e ver um erro, como "Acesso negado". _ Com guardas que correspondem às permissões do servidor, você pode impedir que os usuários vejam erros impedindo-os de visitar a página restrita.

Obtenha Informações De Perfil De Usuário No Angular

Depois que um usuário efetua login com sucesso, a Auth0 envia um ID token para sua aplicação Angular. Os sistemas de autenticação, como Auth0, usam ID tokens na autenticação baseada em token para armazenar em cache as informações do perfil do usuário e fornecê-las a uma aplicação cliente. O armazenamento em cache de ID tokens pode contribuir para melhorias no desempenho e capacidade de resposta da sua aplicação Angular.

Você pode usar os dados do ID token para personalizar a interface do usuário da sua aplicação Angular. O SDK da Auth0 para Angular decodifica o ID token e armazena seus dados através do observable

user$
exposto por
AuthService
. Algumas das informações do ID token incluem o nome, apelido, imagem e e-mail do usuário conectado.

Como você pode usar o ID token para criar uma página de perfil para seus usuários?

Atualize

src/app/features/profile/profile.component.ts
assim:

import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { map } from 'rxjs/operators';

@Component({
 selector: 'app-profile',
 templateUrl: './profile.component.html',
})
export class ProfileComponent {
 title = 'Decoded ID Token';

 user$ = this.authService.user$;
 code$ = this.user$.pipe(map((user) => JSON.stringify(user, null, 2)));

 constructor(private authService: AuthService) {}
}

Depois, atualize

src/app/features/profile/profile.component.html
assim:

<app-page-layout>
  <div class="content-layout">
    <h1 id="page-title" class="content__title">Profile Page</h1>
    <div class="content__body">
      <p id="page-description">
        <span>
          You can use the <strong>ID Token</strong> to get the profile
          information of an authenticated user.
        </span>
        <span>
          <strong>Only authenticated users can access this page.</strong>
        </span>
      </p>

      <ng-container *ngIf="user$ | async as user">
        <div class="profile-grid">
          <div class="profile__header">
            <img [src]="user.picture" alt="Profile" class="profile__avatar" />
            <div class="profile__headline">
              <h2 class="profile__title">{{ user.name }}</h2>
              <span class="profile__description">{{ user.email }}</span>
            </div>
          </div>
          <ng-container *ngIf="code$ | async as code">
            <div class="profile__details">
              <app-code-snippet
                [title]="title"
                [code]="code"
              ></app-code-snippet>
            </div>
          </ng-container>
        </div>
      </ng-container>
    </div>
  </div>
</app-page-layout>

O que está acontecendo em

ProfileComponent
?

  • Você exibe três propriedades do objeto
    user
    na interface do usuário:
    name
    ,
    picture
    , e
    email
    .
  • Como os dados vêm de um Observable, você não precisa inscrevê-los diretamente no modelo usando a
    async
    pipe.
  • Por fim, você exibe o conteúdo completo do ID token decodificado em uma caixa de código. Agora você pode ver todas as outras propriedades disponíveis para você usar. As propriedades são conhecidas como "token claims" (atributos de token).

O

ProfileComponent
processa informações do usuário que você pode considerar privadas ou confidenciais. Além disso, a propriedade do
user
é
null
se não houver nenhum usuário conectado. De qualquer forma, esse componente só deve renderizar se Auth0 tiver autenticado o usuário. Você já está restringindo o acesso a este componente de página usando o
authGuard
para proteger a definição de rota
/profile
do seu módulo roteador Angular,
src/app/app-routing.module.ts
.

Se você estiver conectado à sua aplicação, visite

http://localhost:4040/profile
para ver os detalhes do seu perfil de usuário.

Integre O Angular Com Um Servidor De API

Esta seção se concentra em mostrar como obter um access token em sua aplicação Angular e como usá-lo para fazer chamadas de API para endpoints de API protegidos.

Ao usar a Auth0, você delega o processo de autenticação a um serviço centralizado. A Auth0 oferece a funcionalidade de fazer login e logout de usuários da aplicação Angular. No entanto, sua aplicação pode precisar acessar recursos protegidos de uma API.

Você também pode proteger uma API com Auth0. Existem vários guias de início rápido de API para te ajudar a integrar a Auth0 com sua plataforma de back-end.

Ao usar a Auth0 para proteger sua API, você também delega o processo de autorização a um serviço centralizado que garante que apenas aplicações de cliente aprovadas possam acessar recursos protegidos em nome de um usuário.

Como você pode fazer chamadas de API seguras a partir do Angular?

Sua aplicação Angular autentica o usuário e recebe um token de acesso da Auth0. A aplicação pode então passar esse token de acesso para sua API como uma credencial. Por sua vez, sua API pode usar bibliotecas Auth0 para verificar o token de acesso que recebe da aplicação e emitir uma resposta com os dados desejados.

Em vez de criar uma API do zero para testar o fluxo de autenticação e autorização entre o cliente e o servidor, você pode emparelhar essa aplicação cliente com um servidor de API que corresponda à stack de tecnologia que você usa no trabalho. A aplicação cliente Angular "Hello World" que você construiu pode interagir com qualquer uma das amostras de servidor da API "Hello World" do Auth0 Developer Center.

As amostras do servidor de API "Hello World" são executadas em

http://localhost:6060
por padrão, que é a mesma URL de origem e porta em que o servidor JSON simulado está sendo executado. Assim, antes de configurar o servidor da API "Hello World", localize a guia onde você está executando o comando
npm run api
e interrompa o servidor JSON simulado.

Escolha um exemplo de código de API no seu framework back-end preferido na lista abaixo e siga as instruções na página de exemplo de código para configurá-lo. Depois de concluir a configuração do servidor de API de exemplo, retorne a esta página para aprender como integrar esse servidor de API com sua aplicação Angular (os exemplos listados abaixo estão em inglês):

Chame Uma API Protegida Do Angular

Depois de configurar a amostra de código do servidor API, você deve ter criado um valor Auth0 Audience. Agora, atualize o arquivo

.env
no diretório do projeto Angular da seguinte maneira:

API_SERVER_URL=http://localhost:6060
AUTH0_DOMAIN=<AUTH0-DOMAIN>
AUTH0_CLIENT_ID=<AUTH0-CLIENT-ID>
AUTH0_CALLBACK_URL=http://localhost:4040/callback
AUTH0_AUDIENCE=<AUTH0-AUDIENCE>

Lembre-se de preencher os valores para as variáveis

AUTH0_DOMAIN
e
AUTH0_CLIENT_ID
com as informações obtidas na página da sua aplicação no dashboard da Auth0 como no início deste guia.

Você está usando

AUTH0_AUDIENCE
para adicionar o valor de sua Auth0 Audience para que sua aplicação cliente Angular possa solicitar recursos da API que esse valor de audiência representa.

Vamos entender melhor o que representam os valores

AUTH0_AUDIENCE
e
API_SERVER_URL
.

O

API_SERVER_URL
é simplesmente a URL onde seu servidor de API de exemplo atende às requisições. Em produção, você irá alterar esse valor para a URL do seu servidor ativo.

Sua aplicação Angular deve passar um token de acesso quando chama uma API de destino para acessar recursos protegidos. Você pode solicitar um token de acesso em um formato que a API possa verificar passando o

audience
para o SDK da Auth0 para Angular.

O valor de Auth0 Audience deve ser o mesmo para a aplicação cliente Angular e o servidor da API que você decidiu configurar.

E por que o valor Auth0 Audience é o mesmo para ambas as aplicações? A Auth0 usa o valor

audience
para determinar qual servidor de recurso (API) o usuário está autorizando o acesso da aplicação Angular. É como um número de telefone. Você deseja garantir que sua aplicação Angular "envie mensagem para a API correta".

Assim, atualize o script

set-env.ts
para integrar essas novas variáveis de ambiente Auth0 de
.env
para o seu arquivo Angular
src/environments/environment.ts
:

const { writeFile } = require('fs');
const { promisify } = require('util');
const dotenv = require('dotenv');

dotenv.config();

const writeFilePromisified = promisify(writeFile);

const targetPath = './src/environments/environment.ts';

const envConfigFile = `export const environment = {
 production: false,
 auth0: {
   domain: '${process.env['AUTH0_DOMAIN']}',
   clientId: '${process.env['AUTH0_CLIENT_ID']}',
   authorizationParams: {
     audience: '${process.env['AUTH0_AUDIENCE']}',
     redirect_uri: '${process.env['AUTH0_CALLBACK_URL']}',
   },
 },
 api: {
   serverUrl: '${process.env['API_SERVER_URL']}',
 },
};
`;

(async () => {
  try {
    await writeFilePromisified(targetPath, envConfigFile);
  } catch (err) {
    console.error(err);
    throw err;
  }
})();

Reinicie o seu servidor de desenvolvimento Angular para gerar novamente o arquivo

src/environments/environment.ts
:

npm start

Agora você está incluindo uma propriedade

audience
no objeto de configuração
authorizationParams
que você passa para o método
AuthModule.forRoot()
. Lembre-se que o método
AuthModule
inicializa o módulo de autenticação do sistema.

Que tal usar escopos?

Uma propriedade que você não está configurando diretamente no método

AuthModule.forRoot()
é a propriedade scope. Quando você não passa uma opção
scope
para o SDK da Auth0 para Angular, que ativa
Auth0Plugin
, o SDK por padrão usa os escopos do OpenID Connect:
openid profile email
.

  • openid
    : Este escopo informa ao servidor de autorização Auth0 que o cliente está fazendo uma requisição OpenID Connect para verificar a identidade do usuário. OpenID Connect é um protocolo de autenticação.
  • profile
    : este valor de escopo requer acesso às informações de perfil padrão do usuário, como
    name
    ,
    nickname
    e
    picture
    .
  • email
    : este valor de escopo requer acesso às informações de
    email
    e
    email_verified
    .

Os detalhes dos escopos do OpenID Connect vão para o token de ID. No entanto, você pode definir escopos de API personalizados para implementar o controle de acesso. Você os identifica nas chamadas que suas aplicações clientes fazem para essa API. A Auth0 inclui escopos de API no token de acesso como o valor de declaração de scope.

Os conceitos sobre escopos ou permissões de API são melhor abordados em um tutorial de API Auth0, como "Use TypeScript to Create a Secure API with Node.js and Express: Role-Based Access Control.

O SDK da Auth0 para Angular fornece um

HttpInjector
que anexa automaticamente tokens de acesso a solicitações de saída ao usar o módulo integrado do Angular
HttpClient
. No entanto, você deve configurar o injetor para saber a quais solicitações ele precisa anexar tokens de acesso.

Atualize a configuração do

AuthModule
presente no array
imports
do
AppModule
e adicione o
AuthHttpInterceptor
ao array
providers
da seguinte forma:

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { AuthHttpInterceptor, AuthModule } from '@auth0/auth0-angular';
import { environment as env } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SharedModule } from './shared/shared.module';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    SharedModule,
    AuthModule.forRoot({
      ...env.auth0,
      httpInterceptor: {
        allowedList: [
          `${env.api.serverUrl}/api/messages/admin`,
          `${env.api.serverUrl}/api/messages/protected`,
        ],
      },
    }),
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthHttpInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Vamos detalhar o que está acontecendo no código acima:

Primeiro, você está importando

AuthHttpInterceptor
de
@auth0/auth0-angular
junto com
HTTP_INTERCEPTORS
de
@angular/common/http
.
HTTP_INTERCEPTORS
é um token de vários provedores que representa o array de objetos
HttpInterceptor
registrados.

Em seguida, você está adicionando a propriedade

providers
ao objeto de configuração do
AppModule
da seguinte maneira para registrar o injetor
AuthHttpInterceptor
como um provedor:

providers: [
 {
   provide: HTTP_INTERCEPTORS,
   useClass: AuthHttpInterceptor,
   multi: true,
 },
],

Isso conclui as ligações necessárias para conectar o

AuthHttpInterceptor
com seu ciclo de requisições da aplicação Angular.

Agora, você precisa informar ao SDK a quais solicitações anexar tokens de acesso configurando

AuthModule.forRoot()
. Com base nessa configuração, o Angular corresponderá a URL de qualquer solicitação que você fizer usando
HttpClient
em uma lista de URLs permitidas:

httpInterceptor: {
 allowedList: [`${env.api.serverUrl}/api/messages/admin`, `${env.api.serverUrl}/api/messages/protected`],
},

Se houver uma correspondência, o Angular anexa um token de acesso ao cabeçalho de autorização da solicitação. Você pode usar uma string ou uma expressão regular para a correspondência de URL. Por enquanto, você está permitindo que o Angular anexe um token de acesso às solicitações feitas para

http://localhost:6060/api/messages/protected
e
http://localhost:6060/api/messages/admin
.

Isso é tudo o que é necessário para integrar o Angular com um servidor de API externo que também é protegido pela Auth0 e usar um token de acesso para consumir recursos de servidor protegidos da sua aplicação cliente Angular.

Próximos Passos

Você implementou a autenticação de usuário no Angular para identificar seus usuários, obter informações de perfil de usuário e controlar o conteúdo que seus usuários podem acessar protegendo rotas e recursos de API.

Este tutorial mostrou o caso de uso de autenticação mais comum para uma aplicação Angular: login e logout simples. No entanto, a Auth0 é uma plataforma extensível e flexível que pode te ajudar a chegar mais longe. Se você tiver um caso de uso mais complexo, verifique os Cenários de Arquitetura Auth0 (em inglês) para saber mais sobre os cenários de arquitetura típicos que identificamos ao trabalhar com clientes na implementação da Auth0.

Tem um caso de uso complexo?
Garantiremos que sua equipe de desenvolvimento esteja preparada para o sucesso desde o primeiro dia. Fale com um especialista.

Abordaremos padrões e ferramentas de autenticação avançada em guias futuros, como usar um pop-up em vez de redirecionar os usuários para fazer login, adicionar permissões a tokens de ID, usar metadados para aprimorar perfis de usuário e muito mais.