Angular is a modern framework for developing single page web applications. Angular is developed and backed by Google. Back in days creating the single page applications was a nightmare for developers. We had to manage everything from the state management to the HTTP calls.

But those days are definitely gone.

Now we have the plenty JavaScript frameworks available on the market, ready for the development process of the amazing web applications. Angular is one of those frameworks. It’s both popular and feature-rich framework that you can get to know and work with easily.

Creating a rich browser application is awesome but implementing the security is equally important if not even more.

In this blog post, we are going to learn how we can implement authentication and authorization in Angular. We are going to see how we can securely transfer the user’s credentials from a browser to a server and vice versa.

This part is the continuation of the previous part where we have briefly covered the JWT authentication backend side. In this part, we are going to consume that Web API in our Angular application.

You can download the source code for the starting projects here and for the finished projects here.

This blog is divided into following sections:

Enabling Cross-Origin Requests (CORS)

By default, you can’t send an AJAX request over HTTP to servers on a different origin due to browser’s security concerns. The HTTP protocol is not a secure protocol as it sends the requests in the plain text (at least HTTP v1 does) and anyone can potentially use a web proxy software to intercept modify the request.

On the other hand, the HTTPS protocol is a secure way to transfer information and some browsers by default allow requests to cross-origin servers on HTTPS.

So, what can we do?

We need to configure the server to receive cross-origin requests. By default, ASP.NET Core application will reject any request coming from the cross-origin clients. To enable CORS in .NET Core Web API, we need to implement a middleware in the Configure method of the Startup class.

Let’s open the webapplication-start project (you may find it in here) and add the code to the ConfigureServices method to configure the CORS policy:

To make this middleware available for the application, add the following code in the Configure method:

We can find out more about CORS and the additional options to configure it on this location: CORS Configuration.

Perfect.

At this point, the server is ready to listen to the cross-origin requests.

Implementing Login

We have created the Angular starter application (available for download from here) which contains all the necessary code (basic Angular components, the routes, and basic form validation) we need for this post. With this project, it is going to be much easier for us to follow along with this post, because we can focus only on the parts important for the JWT authentication. To find out in detail how to work with Angular, visit our Angular Series.

Let’s download the starter Angular application, so we could easily follow all the coding parts.

To implement the login, we are going to create the login method in the LoginComponent. Inside the login method, we are going to collect the username and the password from the login form. When a user presses the login button, we are going to collect the user’s credentials with the Angular event binding.

Once we have the credentials, we are going to send them to the server via the HTTP POST request to the login endpoint. The server is going to validate the data. If the username and password are valid, the server will issue a JSON web token and send it back to the browser. A valid username is “johndoe” and the valid password is “[email protected]“, as you can read in part 1 of the JWT series.

 Let’s implement the login method:

In the code above, we send the HTTP POST request towards the server, by using an HttpClient service defined in the@angular/common/http module. The HttpClient service exposes some helper methods equivalent to HTTP verbs. For example, if we need to send the HTTP POST request to the server, we have the post method in the HttpClient service. The call to each method returns an Observable which is a JavaScript way of making the asynchronous calls.

The Observable Callbacks

The Observable provides three callbacks for us to subscribe to while waiting for the response. The first callback is called when Observable receives a successful response. The second callback is called when there is an error. The third callback is called whether there is the response or an error, it’s a way of signaling that the request is completed.

In the response callback, we get the token from the server and we save the token in the browser’s local storage. The browser’s local storage is a collection of the key-value pairs that browser stores per website.

Once we have the token persisted in a storage, we can use it for future calls to access the protected resources on the server. You can think of a token as a special identity card that you may use to access the secret resources in your organization.

Let’s continue with the login form implementation in the login.component.html file:

Implementing Logout

Implementing the logout function is very simple. It’s similar to losing the identity card. If we don’t have the card, we are not able to access the secretly protected resources. To log out the user, we are simply going to delete the token stored in the local storage which is the only key to access protected resources.

If we don’t have the token, the server simply doesn’t know our identity and it’s going to reject our calls to the protected resources. To implement log out we are going to create the logout method in the HomeComponent. Inside the logout method, we are going to remove the token from the local storage and that’s all.

To perform the log out action, we need to press the logout link on the Home page.

So far so good.

At this point our logout functionality is complete.

Protecting Angular Routes

Protecting the Angular routes is the crucial part of implementing security in the Angular application. To protect the routes, Angular provides the CanActivate interface. This interface exposes the canActivate method which we can implement to provide a route guard. The canActivate method triggers before the Angular route activates, it acts as a guard to the Angular routes. Inside the canActivate method, we can write any custom logic to protect our routes.

In the folder named guards, we can find the auth-guard.service.ts file. Let’s implement the AuthGuard logic which provides a custom implementation of the CanActivate interface:

Inside the canActivate method, we are going to check if the token expired. To check the validity of a token, we are using the JwtHelper service. The JwtHelper service is defined in the angular2-jwt library which is a lightweight library that provides some helper services to easily work with JSON web tokens in Angular.

To install the angular2-jwt library, run the following command in the terminal window:

Now, we are going to apply the AuthGuard service to the CustomersComponent route in the AppModule. To apply the AuthGuard, we simply provide the service name in the CustomersComponent‘s route object by using thecanActivate attribute.

Following is the code snippet to activate the AuthGuardservice for the CustomerComponent route in the app.module.ts file:

The canActivate property in the Route object is an array. That means you can specify more than one services.

Accessing Protected Resources

To access the protected resources we need to send the JWT token in the Authorization header with each request. The server is going to verify the token and grant the access to the protected resources.

In our CustomerComponent, on the component initialization, we are going to send a request to the server to access a list of customers.

In the code snippet above, we are sending an HTTP GET request to the endpoint http://localhost:5000/api/customers with the JSON web token in the Authorization header. If the token is invalid the server is going to reply with the 401 Unauthorized response. If the token is valid, then we are going to see a list of customers.

Role-Based Authorization

Right now, we have a fully functional application (the backend and the frontend part) which uses the JWT features for the user authentication. But, because we have only the [Authorize] attribute on top of the Customers controller’s GET action, all the authenticated users have access to that endpoint.

What if we don’t want this type of behavior? What if we want only Managers to have access to that endpoint?

Well, to accomplish that, we need to make a couple of changes on our Web API part.

First, let’s modify the [Authorize]attribute to give access only to a user with the Manager role:

Excellent.

Additionally, let’s modify the Login method in the AuthController to set up the user claims:

In the changed parts of the code, we create claims by adding the username and the role claim to the Claim list. Now, our “johndoe” user is a Manager and it should have access to the Customer’s GET action. These claims are going to be included in our token. If we try to login with the Angular application, everything should work as before without any problems.

All the JWT related logic is inside our Login method for the sake of simplicity. But we encourage you to create a new class (JwtConfigurator or use any other name) and transfer all the SymmetricSecurityKey, SigninCredentials, Claims and JWtSecurityToken logic to a new class.

Finally, let’s check what is going to happen if the “johndoe” has the Operator role and not the Manager role. To simulate this, we need to modify the role claim from the Manager to the Operator:

Now, we still are able to log in but once we try to access the Customer’s GET action, we are going to get the 403 Forbidden response:

jwt-forbidden in Angular JWT

Awesome, our authorization part works like a charm.

JwtHelper DecodeToken

One more thing though. Let’s see how we can extract the data from the token on the client side.

The jwtHelper service has the decodeToken function which can decode our token into the JSON object. Because we have already injected the JwtHelper service into the AuthGuard service, let’s modify that service a bit just to see how the decodeToken function works. We are going to add one line of code that checks if the token exists and if it hasn’t expired:

Here is the result:

Conclusion

By reading this post you have learned:

  • How to configure cross-origin requests in the browser and on server
  • To login user in AngularStore save JWT in local storage.
  • How to remove JWT from local storage and how to log out a user in Angular
  • To protect Angular routes with the CanActivate interface
  • How to access protected resources on the server by sending token in the Authorization header

For any suggestion or question, don’t hesitate to comment below.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published Angular content we encourage you to subscribe to our blog.