User Authentication

When the backend is ready, it's time for frontend. In this lesson you will integrate user API with Angular. You will implement the user authentication flow.

User Authentication#

Once the application's backend and the API are ready, it's time to go forward and build the frontend Angular application.

To be able to retrieve data using the API, remember to keep your backend built and running:

You are now about to implement the user authentication flow:

  • The FavoritesComponent component will display the user's favorite products.

  • The AuthGuard service will protect FavoritesComponent from unauthorized access.

  • In case of unauthorized access, the user will be redirected to LoginComponent.

To generate these components and services, type the following commands in a new terminal window:

Adjusting AppModule#

The code you are about to implement will depend on two modules that AppModule does not import by default: HttpClientModule and ReactiveFormsModule.

To fix this, add two import statements to src/app/app.module.ts:

Then update the imports table:

User service#

Before you start coding UserService, you need to implement the User model that it will be using.

Create a new folder, src/model/. Inside this folder, add a new file, user.model.ts, with the following code:

Now you can start implementing UserService. Start with declaring class fields, injecting services that you'll need, and checking if the user is authenticated. Add the following code to src/app/user.service.ts:

The code above introduces four variables:

  • API_URL is the URL of the API that the service is going to communicate with.

  • currentUser$ is an Observable representing the currently authenticated user, or null if there is no authenticated user.

  • redirectUrl is a placeholder that AuthGuard uses to define where the user should be redirected after successful authentication.

  • redirectParams represents path params of the URL above.

The constructor injects two services:

  • HttpClient is used to perform HTTP calls to the API.

  • Router is used to redirect the user to the desired URL after successful authentication.

Within the constructor, you've piped the currentUser$ observable with a set of operators that includes a call to the checkCookie() function whenever the value of currentUser$ changes to null.

Notice that you've called the subscribe() method of the currentUser$ object. You should be aware of keeping opened subscriptions in your code, because doing this may lead to memory leaks.

Keeping a subscription open is only acceptable here because we're dealing with a service. Thanks to the Dependency Injection mechanism, you are guaranteed that you will only have one instance of this class (UserService) in your application.

As to components, you should avoid opening subscriptions to them whenever you can. Components can be instantiated multiple times during your application lifecycle, which makes them difficult to manage. If you have an Observable in a component, it is much better to pass it to the template and let an async pipe handle subscribing to and unsubscribing from it.

The checkCookie() function calls the /api/isLoggedIn endpoint, which checks that the cookie exists and validates its content. Based on the API's response, checkCookie() emits the logged-in user (or null) using the currentUser$ observable.

Because you've set up your cookie as httpOnly, it isn't reachable by JavaScript. Moreover, even if it were set as a regular cookie, its value is encrypted. Without a key, you're unable to read its content.

Once you're done with handling service instantiation, it's time to implement the login functionality:

The code above introduces the following functions:

  • isLoggedIn() returns an Observable emitting a boolean value based on what is emitted by currentUser$.

  • setRedirectUrl() is a setter for the redirectUrl field.

  • login() is responsible for user authentication using email and password passed as parameters. It's emitting authenticated user data via the currentUser$ observable, based on response from the api/login endpoint. When the user is authenticated, they are redirected to the URL specified in the redirectUrl variable.

 

This page is a preview of The newline Guide to Angular Universal

No discussions yet