跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) LLM(84) angular(83) 大语言模型(67) 人工智能(56) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(34) Go基础(29) Python(24) Vue(23) Web开发(20) 深度学习(20) Web技术(19) 精选资源(19) Java(19) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) LLMOps(11) 聊天机器人(11) 安卓(11) ChatGPT(10) typescript(10) 资料精选(10) mlops(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) RAG(9) Go语言中级开发(9) 自然语言处理(9) PostgreSQL(9) 区块链(9) 安全(9) 智能体(8) 全栈开发(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 数据科学(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) whisper(6) Prisma(6) 隐私保护(6) 提示工程(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 生成式AI(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) kafka(5) 推荐系统(5) WebAssembly(5) GameDev(5) 数据分析(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) nextjs(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) RAG架构(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) 编程语言(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 模型评估(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

category

了解如何使用Observables和HTTP拦截器将用户身份验证添加到Angular。

This guide supports Angular 9, whose long-term support (LTS) ended on August 6, 2021.

The focus of this guide is to help developers learn how to secure an Angular application by implementing user authentication. You'll enhance an Angular starter application to practice the following security concepts:

  • Add user login and logout.
  • Retrieve user profile information.
  • Protect application routes.
  • Call an API with protected endpoints.

This tutorial uses the Auth0 Angular SDK to secure Angular applications. The SDK abstracts a lot of authentication implementation details to help you follow security best practices using an idiomatic Angular approach while writing less code. You don't need to be an expert on OAuth 2.0 or OpenID Connect to understand how to secure your web application stack.

Auth0 Angular sample app

⏰⚡️ If you are short of time, check out the Auth0 Angular Quickstart.

Get the Starter Application

Look for the 🛠️️ emoji if you'd like to skim through the content while focusing on the build steps.

We have created a starter project using the Angular CLI to help you learn Angular security concepts through hands-on practice. The starter project uses a custom Bootstrap theme to style and layout the application so that you can focus on building and wiring Angular components.

🛠 As such, clone the auth0-angular-sample repository on its starter branch to get started:

git clone -b starter git@github.com:auth0-blog/auth0-angular-sample.git

🛠 Once you clone the repo, make auth0-angular-sample your current directory:

cd auth0-angular-sample

🛠 Proceed to install the Angular project dependencies:

npm install

🛠 Finally, run the Angular application:

npm start

Connect Angular with Auth0

Why use Auth0 instead of building your own user authentication from scratch?

In the past, wise folks warned, "thou shalt not roll thee own crypto". Today, wise folks advise that "you don't need to build your own authentication".

Building a comprehensive authentication and authorization system from scratch is complex. Auth0 is an Identity-as-a-Service (IDaaS) platform that lets you centralize user authentication and API authorization for all your applications to reduce that complexity.

Auth0 offers powerful security features out-of-the-box. A customizable login page, social login, Multi-Factor Authentication (MFA), and advanced user management allow you to go live in record time. Perhaps the most important feature is anomaly detection, which helps you combat credential stuff attacks.

At Auth0, credential stuffing attacks account for, on average, nearly half of all login attempts using our platform. Read more details about this critical attack vector: Credential Stuffing Attacks: What Are They and How to Combat Them.

How does Auth0 work?

  • You start by integrating Auth0 with your Angular application.

  • When your users need to log in, your Angular application triggers an authentication event, which it handles by redirecting them to a customizable Auth0 login page.

  • Once your users log in successfully, Auth0 redirects them back to your Angular application, returning tokens with their authentication and user information.

  • Additionally, you can protect your APIs with Auth0 so that you can use an access token to make a request from your Angular application to your protected API endpoints.

How easy is it to get started?

Very easy! Just follow these steps:

Configure an Auth0 Application

If you haven't already,sign up for a free Auth0 account →

A free account offers you:

During the sign-up process, you create something called an Auth0 Tenant, which is a container that Auth0 uses to store your identity service configuration and your users in isolation. No other Auth0 customer can peek into or access your tenant.

🛠 Once you sign in, Auth0 takes you to the Dashboard, where you can manage and configure your identity services. In the left sidebar menu, click on "Applications".

🛠 Then, click the "Create Application" button. A modal opens up with a form to provide a name for the application and choose its type.

  • Name:
Auth0 Angular Sample
  • Application Type:
Single Page Web Applications

🛠 Click the "Create" button to complete the process. Your Auth0 application page loads up.

In the next step, you'll learn how to help Angular and Auth0 communicate using configuration data from that page — don't close it yet.

What's the relationship between Auth0 Tenants and Auth0 Applications?

 

 

Create a communication bridge between Angular and Auth0

When you use Auth0, there's no need to build login forms. Auth0 offers a Universal Login page to reduce the overhead of adding and managing authentication.

It's important to highlight that the Auth0-provided form (Auth0 Universal Login) mitigates the risk of username and password enumeration. Auth0 Universal Login implements authentication error messages correctly following the recommendations of OWASP (The Open Web Application Security Project): say enough to help the user who is logging in but don't say too much to help the attacker trying to break in.

Auth0 Universal Login authentication error messages

How does Universal Login work?

Your Angular application will redirect users to Auth0 whenever they trigger an authentication request. Auth0 will present them with the Universal Login page. Once they log in, Auth0 will redirect them to your application. For that redirecting to happen securely, you must specify in your Auth0 Application Settings the URLs to which Auth0 can redirect users once it authenticates them.

🛠 As such, click on the "Settings" tab of your Auth0 Application page and fill in the following values:

🛠 Allowed Callback URL

http://localhost:4040

After your users successfully log in, Auth0 can only redirect them to any of the URLs you list here.

🛠 Allowed Logout URL

http://localhost:4040

After your users log out, Auth0 can only redirect them to any of the URLs you list here.

🛠 Allowed Web Origins

http://localhost:4040

Using the Auth0 Angular SDK, your Angular application will make requests under the hood to an Auth0 URL to handle authentication requests. As such, you need to add your Angular application origin URL to avoid Cross-Origin Resource Sharing (CORS) issues.

🛠 Scroll down and click the "Save Changes" button.

🛠 Don't close this page yet as you'll need some of its information in the next section.

Add the Auth0 configuration variables to Angular

From the Auth0 Application Settings page, you need the Auth0 Domain and Client ID values to allow your Angular application to use the communication bridge you just created:

What exactly is an Auth0 Domain and an Auth0 Client ID?

 

 


 

 

 

 

 

🛠 Open the Angular starter project, auth0-angular-sample, and create an auth_config.json file under the project directory:

  • macOS/Linux:
touch auth_config.json
  • Windows Powershell:
ni auth_config.json

🛠 Populate auth_config.json as follows:

{
  "domain": "YOUR_AUTH0_DOMAIN",
  "clientId": "YOUR_AUTH0_CLIENT_ID"
}

🛠 Head back to your Auth0 application page. Follow these steps to get the domain and clientId values:

Auth0 application settings to enable user authentication

  1. 🛠 Click on the "Settings" tab, if you haven't already.

  2. 🛠 Use the "Domain" value from the "Settings" as the value of domain in auth_config.json.

  3. 🛠 Use the "Client ID" value from the "Settings" as the value of clientId in auth_config.json.

These variables let your Angular application identify itself as an authorized party to interact with the Auth0 authentication server to carry out the authentication process. You are mapping your Angular application to an Auth0 application.

To use these variables within your Angular application, you'll leverage the Angular environment module.

🛠 Replace the content of src/environments/environment.ts with the following:

// src/environments/environment.ts

import { domain, clientId } from '../../auth_config.json';

export const environment = {
  production: false,
  auth: {
    domain,
    clientId,
    redirectUri: window.location.origin,
  },
};

How is it possible to import JSON files within an Angular module? The starter project has a tsconfig.base.json file that sets the resolveJsonModule to true, which allows you to import and extract types from .json files.

Auth0 and Angular connection set

You have completed setting up an authentication service that your Angular application can consume. All that is left is for you to continue building up the starter project throughout this tutorial by adding security components and features.

Feel free to dive deeper into the Auth0 Documentation to learn more about how Auth0 helps you save time on implementing and managing identity.

Set Up the Auth0 Angular SDK

🛠 You need to follow these steps to integrate the Auth0 Angular SDK with your Angular application.

Install the Auth0 Angular SDK

🛠 Execute the following command:

This is an older version of the Auth0 Angular SDK. Please follow the "Angular Authentication By Example" developer guide instead to use the latest version.

ng add @auth0/auth0-angular@1.11.1

The Auth0 Angular SDK exposes several methods, variables, and types that help you integrate Auth0 with your Angular application idiomatically, including an authentication module and service.

Register and configure the authentication module

The SDK exports a module with the components and services you need to perform user authentication. Import this module into AppModule to access it through Angular's dependency injection framework.

🛠 Import AuthModule and environment right above the @NgModule definition in src/app/app.module.ts as follows:

// src/app/app.module.ts

// Other imports...

import { AuthModule } from '@auth0/auth0-angular';
import { environment as env } from '../environments/environment';

@NgModule({...})
export class AppModule {}

🛠 Then, add AuthModule to the AppModule imports and initialize it:

// src/app/app.module.ts

// All imports...

@NgModule({
  declarations: [...],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FontAwesomeModule,
    // 👇 add and initialize AuthModule
    AuthModule.forRoot({
      ...env.auth,
    }),
  ],
  bootstrap: [...],
})
export class AppModule {}

You use the forRoot() pattern to configure AuthModule, which takes an object with the domain and clientId properties. You create that configuration object by spreading the env.auth object.

User authentication is a mechanism to monitor who is accessing your application and control what they can do. For example, you can prevent users who have not logged in from accessing parts of your application. In that scenario, Auth0 can act as your application bouncer.

bouncer is a person employed by a nightclub or similar establishment to prevent troublemakers from entering or to eject them from the premises. Angular security is not too different from nightclub security.

If users want to enter a protected route from your application, Auth0 will stop them and ask them to present their credentials. If Auth0 can verify who they are and that they are supposed to go in there, Auth0 will let them in. Otherwise, Auth0 will take them back to a public application route.

Now, it's important to reiterate that the authentication process won't happen within your application layer. Your Angular application will redirect your users to the Auth0 Universal Login page, where Auth0 asks for credentials and redirects the user back to your application with the result of the authentication process.

The Auth0 Angular SDK is all set up. You are ready to create components to implement the authentication flow in the next section.

Add User Authentication

The Auth0 Angular SDK gives you methods to trigger authentication events within Angular components: login, logout, and sign up.

Create a login button

🛠 Create a LoginButtonComponent under the src/components/ directory using the Angular CLI:

ng generate component components/login-button --inlineStyle --skipTests

🛠 Populate the login-button.component.ts file in the src/app/components/login-button/ directory like so:

// src/app/components/login-button/login-button.component.ts

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

@Component({
  selector: 'app-login-button',
  templateUrl: './login-button.component.html',
  styles: [],
})
export class LoginButtonComponent implements OnInit {
  constructor(public auth: AuthService) {}

  ngOnInit(): void {}

  loginWithRedirect(): void {
    this.auth.loginWithRedirect();
  }
}

🛠 Next, populate the login-button.component.html template file in the src/app/components/login-button/ directory like so:

<!-- src/app/components/login-button/login-button.component.html -->

<button class="btn btn-primary btn-block" (click)="loginWithRedirect()">
  Log in
</button>

Within the LoginButtonComponent definition, auth.loginWithRedirect() is a method exposed by AuthService. This method prompts the users to authenticate and confirm consent, which means to authorize your Angular application to access certain data on behalf of the user. In your current context, this means that your Angular application redirects the user to the Auth0 Universal Login page to carry out the authentication process. You'll see this in action in the next sections.

You can customize the login experience by passing a configuration object as an argument to loginWithRedirect(). For example, you can pass options to loginWithRedirect() to redirect users to an Auth0 Universal Login page optimized for signing up for your Angular application. See RedirectLoginOptions for more details on these options.

Create a sign-up button

You can make users land directly on a sign-up page instead of a login page by adding the screen_hint property to the configuration object of auth.loginWithRedirect():

{
  screen_hint: "signup",
}

🛠 Create a SignupButtonComponent under the src/components/ directory using the Angular CLI:

ng generate component components/signup-button --inlineStyle --skipTests

🛠 Populate the signup-button.component.ts file in src/app/components/signup-button/ like so:

// src/app/components/signup-button/signup-button.component.ts

import { Component, OnInit } from '@angular/core';

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

@Component({
  selector: 'app-signup-button',
  templateUrl: './signup-button.component.html',
})
export class SignupButtonComponent implements OnInit {
  constructor(public auth: AuthService) {}

  ngOnInit(): void {}

  loginWithRedirect(): void {
    this.auth.loginWithRedirect({ screen_hint: 'signup' });
  }
}

🛠 Populate the signup-button.component.html template file in src/app/components/signup-button/ like so:

<button class="btn btn-primary btn-block" (click)="loginWithRedirect()">
  Sign Up
</button>

The sign-up feature requires you to enable the Auth0 New Universal Login Experience in your Tenant.

🛠 Open the Universal Login section of the Auth0 Dashboard and choose the "New" option under the "Experience" subsection.

Auth0 Universal Login Experience options

🛠 Scroll down and click on the "Save Changes" button.

The difference between the LoginButtonComponent and SignupButtonComponent user experience will be more evident once you integrate those components in your Angular application and see them in action. You'll do that in the next sections.

Create a logout button

🛠 Create a LogoutButtonComponent under the src/components/ directory as follows:

ng generate component components/logout-button --inlineStyle --skipTests

🛠 Populate the logout-button.component.ts file in src/app/components/logout-button/ with this code:

// src/app/components/logout-button/logout-button.component.ts

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

@Component({
  selector: 'app-logout-button',
  templateUrl: './logout-button.component.html',
  styles: [],
})
export class LogoutButtonComponent implements OnInit {
  constructor(
    public auth: AuthService,
    @Inject(DOCUMENT) private doc: Document,
  ) {}

  ngOnInit(): void {}

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

You are defining a logout() method that triggers the logout event. You pass it an optional configuration object to tell Auth0 where to take users after it logs them out.

🛠 Next, populate the logout-button.component.html template file in the src/app/components/logout-button/ directory like so:

<!--src/app/components/logout-button/logout-button.component.html-->

<button class="btn btn-danger btn-block" (click)="logout()">Log out</button>

The auth.logout() method exposed by AuthService clears the application session and redirects to the Auth0 /v2/logout endpoint to clear the Auth0 session. As with the login methods, you can pass a configuration object to logout() to define parameters for the /v2/logout call. This process is fairly invisible to the user. See LogoutOptions for more details.

Here, you add the returnTo property to the configuration object to specify the URL where Auth0 should redirect your users after they logout. Right now, you are working locally, and your Auth0 application's "Allowed Logout URLs" point to http://localhost:4040.

However, if you were to deploy your Angular application to production, you need to add the production logout URL to the "Allowed Logout URLs" list and ensure that Auth0 redirects your users to that production URL and not localhost. Setting returnTo to this.doc.location.origin will do just that.

Angular components don't have direct access to the document object. However, you can @Inject the DOCUMENT constant as a dependency on AuthenticationButtonComponentthis.doc is the same as the DOM document in the browser. this.doc.location returns a Location object whose origin property is the origin of your application.

Read more about how Logout works at Auth0.

Integrate the login and logout buttons

Let's wrap LoginButtonComponent and LogoutButtonComponent in a single component that has logic to decide which button to render depending on the authentication status of the user.

🛠 Create an AuthenticationButtonComponent under the src/app/components/ directory:

ng g c components/authentication-button --inlineStyle --skipTests

You are using the shorthand g (generate) and c (component) to make the command shorter.

🛠 Populate the authentication-button.component.ts file in the src/app/components/authentication-button/ directory like so:

// src/app/components/authentication-button/authentication-button.component.ts

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

@Component({
  selector: 'app-authentication-button',
  templateUrl: './authentication-button.component.html',
  styles: [],
})
export class AuthenticationButtonComponent implements OnInit {
  constructor(public auth: AuthService) {}

  ngOnInit(): void {}
}

🛠 Populate the authentication-button.component.html file in the src/app/components/authentication-button/ directory like so:

<!--
src/app/components/authentication-button/
  authentication-button.component.html
-->

<app-login-button *ngIf="(auth.isAuthenticated$ | async) === false">
</app-login-button>

<app-logout-button *ngIf="auth.isAuthenticated$ | async"> </app-logout-button>

Let's start with understanding what's happening in the template. auth.isAuthenticated$ is an Observable exposed by AuthService that emits a boolean value. Its value is true when Auth0 has authenticated the user and false when it hasn't.

It's important to note that, under the hood, auth.isAuthenticated$ only starts emitting values once the Auth0 Angular SDK has finished loading. When AuthService.isLoading$ emits false, then auth.isAuthenticated$ emits its value. This operation piping helps prevent false positives in relation to the authentication status of a user. This also causes a small delay in the rendering of the AuthenticationButtonComponent, but you'll fix that soon.

There are some advantages to using this AuthenticationButtonComponent component wrapper:

You can build flexible interfacesAuthenticationButtonComponent serves as a "log in/log out" switch that you can put anywhere you need that switch functionality. However, you still have separate LoginButtonComponent and LogoutButtonComponent for cases when you need their functionality in isolation. For example, you may have a logout button on a page that only authenticated users can see.

You can build extensible interfaces. You can easily swap the LoginButtonComponent with the SignupButtonComponent in AuthenticationButtonComponent to create a "sign up/log out" switch. You could also wrap the "sign up/log out" switch in a NewAuthenticationButtonComponent if you wanted.

You can build declarative interfaces. Using AuthenticationButton, you can add login and logout functionality to the NavBarComponent, for example, without thinking about the implementation details of how the authentication switch works.

🛠 With that in mind, create an AuthNavComponent under the src/components/ directory:

ng g c components/auth-nav --inlineStyle --skipTests

🛠 Populate the auth-nav.component.html file in the src/app/components/auth-nav/ directory like so:

<!--src/app/components/auth-nav/auth-nav.component.html-->

<div class="navbar-nav ml-auto">
  <app-authentication-button></app-authentication-button>
</div>

🛠 Finally, open the nav-bar.component.html template file in the src/app/components/nav-bar/ directory and update it as follows:

<!--src/app/components/nav-bar/nav-bar.component.html-->

<div class="nav-container mb-3">
  <nav class="navbar navbar-expand-md navbar-light bg-light">
    <div class="container">
      <div class="navbar-brand logo"></div>
      <app-main-nav></app-main-nav>
      <app-auth-nav></app-auth-nav>
    </div>
  </nav>
</div>

By having different types of navigation sub-components, you can extend each navigation bar as you need without reopening and modifying the MainNavComponent.

🛠 Go ahead and try to log in. Your Angular application redirects you to the Auth0 Universal Login page. You can use a form to log in with a username and password or a social identity provider like Google. Notice that this login page also gives you the option to sign up.

New Auth0 Universal Login Experience Form

Experiment: Use SignupButtonComponent

 

 

 

New Auth0 Universal Login Experience Signup Page

 

You can customize the appearance of New Universal Login pages. You can also override any text in the New Experience using the Text Customization API.

Notice that when you finish logging in and Auth0 redirects you to your Angular app, the user interface has a blank screen flashing.

The user interface flashes because your Angular app is loading up its services. While it is loading, Angular doesn't know if Auth0 has authenticated the user yet. Your app will know the user authentication status after the Auth0 Angular SDK loads.

🛠 To fix that UI flashing, use the auth.isLoading$ Observable exposed by the AuthService that emits a boolean value to render AppComponent once the Angular SDK has finished loading.

🛠 Open src/app/app.component.ts and update it as follows:

// src/app/app.component.ts

import { Component } from '@angular/core';

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

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

🛠 Open src/app/app.component.html and update like so:

<!--src/app/app.component.html-->

<div id="app" class="d-flex flex-column h-100">
  <div class="container" *ngIf="auth.isLoading$ | async; else loaded">
    <app-loading></app-loading>
  </div>

  <ng-template #loaded>
    <app-nav-bar></app-nav-bar>

    <div class="container flex-grow-1">
      <div class="mt-5">
        <router-outlet></router-outlet>
      </div>
    </div>

    <app-footer></app-footer>
  </ng-template>
</div>

While the SDK is loading, LoadingComponent renders, which has a cool animation.

Retrieving User Information

After a user successfully logs in, Auth0 sends an ID token to your Angular application. Authentication systems, such as Auth0, use ID Tokens in token-based authentication to cache user profile information and provide it to a client application. The caching of ID tokens can contribute to improvements in performance and responsiveness for your Angular application.

You can use the data from the ID token to personalize the user interface of your Angular application. The Auth0 Angular SDK decodes the ID token and emits its data through the auth.user$ Observable exposed by AuthService. Some of the ID token information includes the name, nickname, picture, and email of the logged-in user.

How can you use the ID token to create a profile page for your users?

🛠 Update ProfileComponent in src/app/pages/profile/profile.component.ts as follows:

// src/app/pages/profile/profile.component.ts

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

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
})
export class ProfileComponent implements OnInit {
  profileJson: string = null;

  constructor(public auth: AuthService) {}

  ngOnInit(): void {
    this.auth.user$.subscribe(
      (profile) => (this.profileJson = JSON.stringify(profile, null, 2)),
    );
  }
}

🛠 Update the template of ProfileComponent in src/app/pages/profile/profile.component.html as follows:

<!--src/app/pages/profile/profile.component.html-->

<div *ngIf="auth.user$ | async as user">
  <div class="row align-items-center profile-header">
    <div class="col-md-2 mb-3">
      <img
        [src]="user.picture"
        alt="User's profile picture"
        class="rounded-circle img-fluid profile-picture"
      />
    </div>
    <div class="col-md text-center text-md-left">
      <h2>{{ user.name }}</h2>
      <p class="lead text-muted">{{ user.email }}</p>
    </div>
  </div>

  <div class="row" *ngIf="profileJson">
    <pre class="col-12 text-light bg-dark p-4">{{ profileJson }}</pre>
  </div>
</div>

What's happening within the ProfileComponent component?

ngOnInit() is the best place to initialize data for an Angular component. As such, you subscribe to the this.auth.user$ Observable within ProfileComponent. Once this.auth.user$ emits the user profile object, you use JSON.stringify to format the object and assign it to this.profileJson. In turn, you use the *ngIf directive to render a code box with the user profile JSON object based on the value of profileJson.

ProfileComponent renders user information that you could consider protected. Additionally, the user property is null if there is no logged-in user. So either way, this component should only render if Auth0 has authenticated the user.

As such, you should protect the route that renders this component, http://localhost:4040/profile. You'll learn how to do just that in the next section.

Protecting Routes

From all the sections in this guide, this one is the easiest to implement thanks to the robustness of the Angular Router. The Auth0 Angular SDK exposes an AuthGuard that you can use to protect routes.

🛠 Open src/app/app-routing.module.ts and update it as follows:

// src/app/app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from 'src/app/pages/home/home.component';
import { ProfileComponent } from 'src/app/pages/profile/profile.component';
import { ExternalApiComponent } from 'src/app/pages/external-api/external-api.component';

import { AuthGuard } from '@auth0/auth0-angular';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full',
  },
  {
    path: 'profile',
    component: ProfileComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'external-api',
    component: ExternalApiComponent,
    canActivate: [AuthGuard],
  },
];

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

Requiring user login to access a route is easy: just include the canActivate property in the route definition and add AuthGuard as its value. When users who have not logged in visit that route, your Angular application will redirect them to the login page. After the user logs in, Auth0 will redirect the user to your Angular application, and the AuthService will take the users to the page they intended to access before login.

🛠 You can now test that these two paths, /profile and /external-api, require users to authenticate before they can access them. Log out and try to access the Profile or External API tab. If it works, Angular redirects you to log in with Auth0.

Client-side guards improve the user experience of your Angular application, not its security.

 

 

    •  
    •  
    •  
  •  

Calling an API

This section focuses on showing you how to get an access token in your Angular application and how to use it to make API calls to protected API endpoints.

When you use Auth0, you delegate the authentication process to a centralized service. Auth0 provides you with functionality to log in and log out users from your Angular application. However, your application may need to access protected resources from an API.

You can also protect an API with Auth0. Auth0 offers multiple Auth0 API quickstarts to help you integrate Auth0 with your backend platform.

When you use Auth0 to protect your API, you also delegate the authorization process to a centralized service that ensures only approved client applications can access protected resources on behalf of a user.

How can you make secure API calls from Angular?

Your Angular application authenticates the user and receives an access token from Auth0. The application can then pass that access token to your API as a credential. In turn, your API can use Auth0 libraries to verify the access token it receives from the calling application and issue a response with the desired data.

This Angular guide uses an older version of the Auth0 Angular SDK. Please follow the "Angular Authentication By Example" developer guide to learn how to make calls to a protected API.

Instead of creating an API from scratch to test the authentication and authorization flows between the client and the server, you'll use a demo Express API that I've prepared for you.

Get the Express API demo

🛠 Open a new terminal window and clone the auth0-express-js-sample repo somewhere in your system. Ensure that you clone it outside your Angular project directory.

git clone git@github.com:auth0-blog/auth0-express-js-sample.git

🛠 Once you clone this repo, make the auth0-express-js-sample directory your current directory:

cd auth0-express-js-sample

🛠 Install the Node.js project dependencies:

npm install

Connect the Express API with Auth0

Create a communication bridge between Express and Auth0

This process is similar to how you connected Angular with Auth0.

🛠 Head to the APIs section in the Auth0 Dashboard, and click the "Create API" button.

🛠 Then, in the form that Auth0 shows:

  • Add a Name to your API:
Auth0 Express Sample
  • Set its Identifier value:
https://express.sample
  • Leave the signing algorithm as RS256 as it's the best option from a security standpoint.

Auth0 Dashboard new API form

Identifiers are unique strings that help Auth0 different