GrabDuck

Login Screen and Authentication with Angular2 | 4Dev Web Development Tutorials

:

Angular2 Login Screen
Angular2 Login Screen

Before we start I just want to say that in order to easily understand this tutorial you should already have some basic knowledge about Angular 2, it will involve routing, dependency injection and working with multiple components. I don’t want to make this tutorial too long, so I’m going to skip some small details and go straight to the point, if somehow you find that something is not very clear feel free to comment asking for more information, I’ll try to explain better.

We’re going to create three components in this project, the first will be our login form, the second will be like a private component that only authenticated users can see, and the last one is the application itself containing just the route configurations to determine which of the components should be rendered. We’re also going to create a service where all the authentication rules will be placed.

Instead of showing you a piece of code or a function at a time I’m going to just put the entire code here (class by class) and explain everything at once, I think it’s easier this way.

Let’s start with the service:

import {Injectable} from 'angular2/core';
import {Router} from 'angular2/router';
 
export class User {
  constructor(
    public email: string,
    public password: string) { }
}
 
var users = [
  new User('admin@admin.com','adm9'),
  new User('user1@gmail.com','a23')
];
 
@Injectable()
export class AuthenticationService {
 
  constructor(
    private _router: Router){}
 
  logout() {
    localStorage.removeItem("user");
    this._router.navigate(['Login']);
  }
 
  login(user){
    var authenticatedUser = users.find(u => u.email === user.email);
    if (authenticatedUser && authenticatedUser.password === user.password){
      localStorage.setItem("user", authenticatedUser);
      this._router.navigate(['Home']);      
      return true;
    }
    return false;
 
  }
 
   checkCredentials(){
    if (localStorage.getItem("user") === null){
        this._router.navigate(['Login']);
    }
  } 
}

The first thing you should notice is that we have a users variable with two users (let’s pretend this data is coming from the database), when someone tries to login we’re going to check this list to see if the user exists. I’ve also created three functions: login(), logout() and checkCredentials(). If you take a look at the code you’ll see that I’m using localStorage to store the authenticated user, so basically these functions are responible for respectively adding, removing and checking users on the localStorage.

Although I’ve put these rules on an Angular2 service, I strongly recommend you to let the server control everything regarding user authentication. It’s ok to do this way in this example, but in a real case scenario it just wouldn’t be safe, anyone with a little bit of javascript knowledge would be able to open the web console and modify the values on this service.

Now you must be thinking: Why am I doing it this way if it’s not safe? Well, In order to show you a safer way to do it I would also have to cover some things from the back-end, and since each one of you could be using a different language or framework on the server-side it wouldn’t be easy to write something that meets everyone’s needs, that’s why I’m focusing on Angular 2 on this tutorial. If you need any help integrating it with your back-end please let me know in the comments.

Now let’s move on to the login form:

import {Component, ElementRef} from 'angular2/core';
import {AuthenticationService, User} from './authentication.service'
 
@Component({
    selector: 'login-form',
    providers: [AuthenticationService],
    template: `
        <div class="container" >
            <div class="title">
                Welcome
            </div>
            <div class="panel-body">
                <div class="row">
                    <div class="input-field col s12">
                        <input [(ngModel)]="user.email" id="email" 
                            type="email" class="validate">
                        <label for="email">Email</label>
                    </div>
                </div>
 
                <div class="row">
                    <div class="input-field col s12">
                        <input [(ngModel)]="user.password" id="password" 
                            type="password" class="validate">
                        <label for="password">Password</label>
                    </div>
                </div>
 
                <span>{{errorMsg}}</span>
                <button (click)="login()" 
                    class="btn waves-effect waves-light" 
                    type="submit" name="action">Login</button>
            </div>
        </div>
    	`
})
 
export class LoginComponent {
 
    public user = new User('','');
    public errorMsg = '';
 
    constructor(
        private _service:AuthenticationService) {}
 
    login() {
        if(!this._service.login(this.user)){
            this.errorMsg = 'Failed to login';
        }
    }
}

Since all the logic is on the service this component will be very simple, I’m just injecting the service on the constructor and when the user clicks on login I’m calling the login() function from the service, if everything goes right the service will redirect to the other component, otherwise it will return false and this component will show the message ‘Failed to login’. If you take a look at the template you’ll see lots of different css classes, they are from materilize, but there’s also some that I’ve created myself, as they’re not so relevant for the tutorial I’m not going to put their code here.

Next, let’s create the the PrivateComponent:

import {Component} from 'angular2/core';
import {AuthenticationService} from './authentication.service'
 
@Component({
    selector: 'login-form',
    providers: [AuthenticationService],
    template: `
            <div class="container" >
                <div class="content">
                    <span>Congratulations, you have successfully logged in!!</span>
                    <br />
                    <a (click)="logout()" href="#">Click Here to logout</a>
                </div>
            </div>
    	`
})
 
export class PrivateComponent {
 
    constructor(
        private _service:AuthenticationService){}
 
    ngOnInit(){
        this._service.checkCredentials();
    }
 
    logout() {
        this._service.logout();
    }
}

As I said before, this is just a component that only logged in users can see, so every time someone tries to access it I’m using the lifecycle hook ngOnInit to call the function _service.checkCredentials(), if the user is not logged in he will be redirected to the login screen, otherwise he will be able to see the component, it contains only a message and the logout link.

Lastly, we have the app.component.ts:

import {Component} from 'angular2/core';
import {LoginComponent} from './login.component';
import {PrivateComponent} from './private.component';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
 
@Component({
    selector: 'my-app',
    directives: [LoginComponent, ROUTER_DIRECTIVES],
    template: `
            <router-outlet></router-outlet>
        `
})
@RouteConfig([
    { path: '/home', name: 'Home', component: PrivateComponent, useAsDefault:true },
    { path: '/login', name: 'Login', component: LoginComponent }
])
export class AppComponent {}

Here I’m setting the two routes we’re going to use, one for each component. I’m using /home as the default, so when we launch the application it’ll go straight to the PrivateComponent, then as it doesn’t have any logged in user, it’ll redirect to the login page. Note that I’ve put the router-outlet tag on the template, this is how I’m telling the application where to render our components.

We’re almost done, before we run our project we still have some changes to make on the main.ts in order to make the routes work, here’s how it should look like after the modifications:

import {bootstrap}    from 'angular2/platform/browser'
import {AppComponent} from './app.component'
import {ROUTER_PROVIDERS} from 'angular2/router'
 
bootstrap(AppComponent, [ROUTER_PROVIDERS]);

That’s it! Now you can run your project, if you did everything right you should see the login screen on your browser.

Hope you enjoyed this tutorial, just leave a comment if you have any doubts, till next time!