zoukankan      html  css  js  c++  java
  • Angular 2 User Registration and Login Example & Tutorial


    http://jasonwatmore.com/post/2016/09/29/angular-2-user-registration-and-login-example-tutorial


    Built with Angular 2.0 Final.

    After getting a lot of interest in a previous tutorial I posted on how to build a User Registration and Login with Angular 1, and since Angular 2 Final was recently released I thought it was time to post an updated example built with Angular 2 and TypeScript.

    The project is available on GitHub at https://github.com/cornflourblue/angular2-registration-login-example.

    The example uses a fake backend that stores users in HTML5 local storage, to switch to using a real web service simply remove the fake backend providers in the app.module.ts file below the comment "// providers used to create fake backend".

    Here it is in action: (See on Plunker at http://plnkr.co/edit/9luTng?p=preview)

    Running the Angular 2 User Registration & Login Example Locally

    1. Install NodeJS (> v4) and NPM (> v3) from https://nodejs.org/en/download/, you can check the versions you have installed by running node -v and npm -v from the command line.
       
    2. Download the project source code from https://github.com/cornflourblue/angular2-registration-login-example
       
    3. Install all required npm packages by running npm install from the command line in the project root folder (where the package.json is located).
       
    4. Start the application by running npm start from the command line in the project root folder.


    Angular 2 Project Structure

    I used the Angular 2 quickstart project as a base for the application, it's written in TypeScript and uses systemjs for loading modules. If you're new to angular 2 I'd recommend checking out the quickstart as it provides details on the project tooling and configuration files which aren't covered in this post.

    The project and code structure mostly follows the recommendations in the official Angular 2 style guide, with my own tweaks here and there.

    Each feature has it's own folder (home & login), other code such as services, models, guards etc are placed in folders prefixed with an underscore to easily differentiate them and group them together at the top of the folder structure.

    Here's the project structure:


    Below are brief descriptions and the code for the main files of the example application, all files are available in the github project linked at the top of the post.

     

    Angular 2 Alert Component Template

    Path: /app/_directives/alert.component.html

    The alert component template contains the html for displaying alert messages at the top of the page.

    1
    <div *ngIf="message" [ngClass]="{ 'alert': message, 'alert-success': message.type === 'success', 'alert-danger': message.type === 'error' }">{{message.text}}</div>
     

    Angular 2 Alert Component

    Path: /app/_directives/alert.component.ts

    The alert component passes alert messages to the template whenever a message is received from the alert service. It does this by subscribing to the alert service's getMessage() method which returns an Observable.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import { Component, OnInit } from '@angular/core';
     
    import { AlertService } from '../_services/index';
     
    @Component({
        moduleId: module.id,
        selector: 'alert',
        templateUrl: 'alert.component.html'
    })
     
    export class AlertComponent {
        message: any;
     
        constructor(private alertService: AlertService) { }
     
        ngOnInit() {
            this.alertService.getMessage().subscribe(message => { this.message = message; });
        }
    }
     

    Angular 2 Auth Guard

    Path: /app/_guards/auth.guard.ts

    The auth guard is used to prevent unauthenticated users from accessing restricted routes, in this example it's used in app.routing.ts to protect the home page route. For more information about angular 2 guards you can check out this post on the thoughtram blog.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import { Injectable } from '@angular/core';
    import { Router, CanActivate } from '@angular/router';
     
    @Injectable()
    export class AuthGuard implements CanActivate {
     
        constructor(private router: Router) { }
     
        canActivate() {
            if (localStorage.getItem('currentUser')) {
                // logged in so return true
                return true;
            }
     
            // not logged in so redirect to login page
            this.router.navigate(['/login']);
            return false;
        }
    }
     

    Angular 2 Fake Backend Provider

    Path: /app/_helpers/fake-backend.ts

    The fake backend provider enables the example to run without a backend / backendless, it uses HTML5 local storage for storing registered user data and provides fake implementations for authentication and CRUD methods, these would be handled by a real api and database in a production application.

    It uses the Angular 2 MockBackend to replace the default backend used by the Http service, the MockBackend enables you to intercept http requests made within the application and provide fake responses, it's also used for unit testing.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    import { Http, BaseRequestOptions, Response, ResponseOptions, RequestMethod } from '@angular/http';
    import { MockBackend, MockConnection } from '@angular/http/testing';
     
    export let fakeBackendProvider = {
        // use fake backend in place of Http service for backend-less development
        provide: Http,
        useFactory: (backend, options) => {
            // array in local storage for registered users
            let users: any[] = JSON.parse(localStorage.getItem('users')) || [];
     
            // configure fake backend
            backend.connections.subscribe((connection: MockConnection) => {
                // wrap in timeout to simulate server api call
                setTimeout(() => {
     
                    // authenticate
                    if (connection.request.url.endsWith('/api/authenticate') && connection.request.method === RequestMethod.Post) {
                        // get parameters from post request
                        let params = JSON.parse(connection.request.getBody());
     
                        // find if any user matches login credentials
                        let filteredUsers = users.filter(user => {
                            return user.username === params.username && user.password === params.password;
                        });
     
                        if (filteredUsers.length) {
                            // if login details are valid return 200 OK with user details and fake jwt token
                            let user = filteredUsers[0];
                            connection.mockRespond(new Response(new ResponseOptions({
                                status: 200,
                                body: {
                                    id: user.id,
                                    username: user.username,
                                    firstName: user.firstName,
                                    lastName: user.lastName,
                                    token: 'fake-jwt-token'
                                }
                            })));
                        } else {
                            // else return 400 bad request
                            connection.mockError(new Error('Username or password is incorrect'));
                        }
                    }
     
                    // get users
                    if (connection.request.url.endsWith('/api/users') && connection.request.method === RequestMethod.Get) {
                        // check for fake auth token in header and return users if valid, this security is implemented server side in a real application
                        if (connection.request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
                            connection.mockRespond(new Response(new ResponseOptions({ status: 200, body: users })));
                        } else {
                            // return 401 not authorised if token is null or invalid
                            connection.mockRespond(new Response(new ResponseOptions({ status: 401 })));
                        }
                    }
     
                    // get user by id
                    if (connection.request.url.match(//api/users/d+$/) && connection.request.method === RequestMethod.Get) {
                        // check for fake auth token in header and return user if valid, this security is implemented server side in a real application
                        if (connection.request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
                            // find user by id in users array
                            let urlParts = connection.request.url.split('/');
                            let id = parseInt(urlParts[urlParts.length - 1]);
                            let matchedUsers = users.filter(user => { return user.id === id; });
                            let user = matchedUsers.length ? matchedUsers[0] : null;
     
                            // respond 200 OK with user
                            connection.mockRespond(new Response(new ResponseOptions({ status: 200, body: user })));
                        } else {
                            // return 401 not authorised if token is null or invalid
                            connection.mockRespond(new Response(new ResponseOptions({ status: 401 })));
                        }
                    }
     
                    // create user
                    if (connection.request.url.endsWith('/api/users') && connection.request.method === RequestMethod.Post) {
                        // get new user object from post body
                        let newUser = JSON.parse(connection.request.getBody());
     
                        // validation
                        let duplicateUser = users.filter(user => { return user.username === newUser.username; }).length;
                        if (duplicateUser) {
                            return connection.mockError(new Error('Username "' + newUser.username + '" is already taken'));
                        }
     
                        // save new user
                        newUser.id = users.length + 1;
                        users.push(newUser);
                        localStorage.setItem('users', JSON.stringify(users));
     
                        // respond 200 OK
                        connection.mockRespond(new Response(new ResponseOptions({ status: 200 })));
                    }
     
                    // delete user
                    if (connection.request.url.match(//api/users/d+$/) && connection.request.method === RequestMethod.Delete) {
                        // check for fake auth token in header and return user if valid, this security is implemented server side in a real application
                        if (connection.request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
                            // find user by id in users array
                            let urlParts = connection.request.url.split('/');
                            let id = parseInt(urlParts[urlParts.length - 1]);
                            for (let i = 0; i < users.length; i++) {
                                let user = users[i];
                                if (user.id === id) {
                                    // delete user
                                    users.splice(i, 1);
                                    localStorage.setItem('users', JSON.stringify(users));
                                    break;
                                }
                            }
     
                            // respond 200 OK
                            connection.mockRespond(new Response(new ResponseOptions({ status: 200 })));
                        } else {
                            // return 401 not authorised if token is null or invalid
                            connection.mockRespond(new Response(new ResponseOptions({ status: 401 })));
                        }
                    }
     
                }, 500);
     
            });
     
            return new Http(backend, options);
        },
        deps: [MockBackend, BaseRequestOptions]
    };
     

    Angular 2 User Model

    Path: /app/_models/user.ts

    The user model is a small class that defines the properties of a user.

    1
    2
    3
    4
    5
    6
    export class User {
        username: string;
        password: string;
        firstName: string;
        lastName: string;
    }
     

    Angular 2 Alert Service

    Path: /app/_services/alert.service.ts

    The alert service enables any component in the application to display alert messages at the top of the page via the alert component.

    It has methods for displaying success and error messages, and a getMessage() method that returns an Observable that is used by the alert component to subscribe to notifications for whenever a message should be displayed.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    import { Injectable } from '@angular/core';
    import { Router, NavigationStart } from '@angular/router';
    import { Observable } from 'rxjs';
    import { Subject } from 'rxjs/Subject';
     
    @Injectable()
    export class AlertService {
        private subject = new Subject<any>();
        private keepAfterNavigationChange = false;
     
        constructor(private router: Router) {
            // clear alert message on route change
            router.events.subscribe(event => {
                if (event instanceof NavigationStart) {
                    if (this.keepAfterNavigationChange) {
                        // only keep for a single location change
                        this.keepAfterNavigationChange = false;
                    } else {
                        // clear alert
                        this.subject.next();
                    }
                }
            });
        }
     
        success(message: string, keepAfterNavigationChange = false) {
            this.keepAfterNavigationChange = keepAfterNavigationChange;
            this.subject.next({ type: 'success', text: message });
        }
     
        error(message: string, keepAfterNavigationChange = false) {
            this.keepAfterNavigationChange = keepAfterNavigationChange;
            this.subject.next({ type: 'error', text: message });
        }
     
        getMessage(): Observable<any> {
            return this.subject.asObservable();
        }
    }
     

    Angular 2 Authentication Service

    Path: /app/_services/authentication.service.ts

    The authentication service is used to login and logout of the application, to login it posts the users credentials to the api and checks the response for a JWT token, if there is one it means authentication was successful so the user details including the token are added to local storage.

    The logged in user details are stored in local storage so the user will stay logged in if they refresh the browser and also between browser sessions until they logout. If you don't want the user to stay logged in between refreshes or sessions the behaviour could easily be changed by storing user details somewhere less persistent such as session storage or in a property of the authentication service.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import { Injectable } from '@angular/core';
    import { Http, Headers, Response } from '@angular/http';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/map'
     
    @Injectable()
    export class AuthenticationService {
        constructor(private http: Http) { }
     
        login(username, password) {
            return this.http.post('/api/authenticate', JSON.stringify({ username: username, password: password }))
                .map((response: Response) => {
                    // login successful if there's a jwt token in the response
                    let user = response.json();
                    if (user && user.token) {
                        // store user details and jwt token in local storage to keep user logged in between page refreshes
                        localStorage.setItem('currentUser', JSON.stringify(user));
                    }
                });
        }
     
        logout() {
            // remove user from local storage to log user out
            localStorage.removeItem('currentUser');
        }
    }
     

    Angular 2 User Service

    Path: /app/_services/user.service.ts

    The user service contains a standard set of CRUD methods for managing users, it contains a jwt() method that's used to add the JWT token from local storage to the Authorization header of each http request.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import { Injectable } from '@angular/core';
    import { Http, Headers, RequestOptions, Response } from '@angular/http';
     
    @Injectable()
    export class UserService {
        constructor(private http: Http) { }
     
        getAll() {
            return this.http.get('/api/users', this.jwt()).map((response: Response) => response.json());
        }
     
        getById(id) {
            return this.http.get('/api/users/' + id, this.jwt()).map((response: Response) => response.json());
        }
     
        create(user) {
            return this.http.post('/api/users', user, this.jwt()).map((response: Response) => response.json());
        }
     
        update(user) {
            return this.http.put('/api/users/' + user.id, user, this.jwt()).map((response: Response) => response.json());
        }
     
        delete(id) {
            return this.http.delete('/api/users/' + id, this.jwt()).map((response: Response) => response.json());
        }
     
        // private helper methods
     
        private jwt() {
            // create authorization header with jwt token
            let currentUser = JSON.parse(localStorage.getItem('currentUser'));
            if (currentUser && currentUser.token) {
                let headers = new Headers({ 'Authorization': 'Bearer ' + currentUser.token });
                return new RequestOptions({ headers: headers });
            }
        }
    }
     

    Angular 2 Home Component Template

    Path: /app/home/home.component.html

    The home component template contains html and angular 2 template syntax for displaying a simple welcome message, a list of users and a logout link.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <div class="col-md-6 col-md-offset-3">
        <h1>Hi {{currentUser.firstName}}!</h1>
        <p>You're logged in with Angular 2!!</p>
        <h3>All registered users:</h3>
        <ul>
            <li *ngFor="let user of users">
                {{user.username}} ({{user.firstName}} {{user.lastName}})
                - <a (click)="deleteUser(user.id)">Delete</a>
            </li>
        </ul>
        <p><a [routerLink]="['/login']">Logout</a></p>
    </div>
     

    Angular 2 Home Component

    Path: /app/home/home.component.ts

    The home component gets the current user from local storage and all users from the user service, and makes them available to the template.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import { Component, OnInit } from '@angular/core';
     
    import { User } from '../_models/index';
    import { UserService } from '../_services/index';
     
    @Component({
        moduleId: module.id,
        templateUrl: 'home.component.html'
    })
     
    export class HomeComponent implements OnInit {
        currentUser: User;
        users: User[] = [];
     
        constructor(private userService: UserService) {
            this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
        }
     
        ngOnInit() {
            this.loadAllUsers();
        }
     
        deleteUser(id) {
            this.userService.delete(id).subscribe(() => { this.loadAllUsers() });
        }
     
        private loadAllUsers() {
            this.userService.getAll().subscribe(users => { this.users = users; });
        }
    }
     

    Angular 2 Login Component Template

    Path: /app/login/login.component.html

    The login component template contains a login form with username and password fields. It displays validation messages for invalid fields when the submit button is clicked. On submit the login() method is called as long as the form is valid.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <div class="col-md-6 col-md-offset-3">
        <h2>Login</h2>
        <form name="form" (ngSubmit)="f.form.valid && login()" #f="ngForm" novalidate>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
                <label for="username">Username</label>
                <input type="text" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
                <div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
            </div>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
                <label for="password">Password</label>
                <input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required />
                <div *ngIf="f.submitted && !password.valid" class="help-block">Password is required</div>
            </div>
            <div class="form-group">
                <button [disabled]="loading" class="btn btn-primary">Login</button>
                <img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
                <a [routerLink]="['/register']" class="btn btn-link">Register</a>
            </div>
        </form>
    </div>
     

    Angular 2 Login Component

    Path: /app/login/login.component.ts

    The login component uses the authentication service to login and logout of the application. It automatically logs the user out when it initializes (ngOnInit) so the login page can also be used to logout.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
     
    import { AlertService, AuthenticationService } from '../_services/index';
     
    @Component({
        moduleId: module.id,
        templateUrl: 'login.component.html'
    })
     
    export class LoginComponent implements OnInit {
        model: any = {};
        loading = false;
     
        constructor(
            private router: Router,
            private authenticationService: AuthenticationService,
            private alertService: AlertService) { }
     
        ngOnInit() {
            // reset login status
            this.authenticationService.logout();
        }
     
        login() {
            this.loading = true;
            this.authenticationService.login(this.model.username, this.model.password)
                .subscribe(
                    data => {
                        this.router.navigate(['/']);
                    },
                    error => {
                        this.alertService.error(error);
                        this.loading = false;
                    });
        }
    }
     

    Angular 2 Register Component Template

    Path: /app/register/register.component.html

    The register component template contains a simplae registration form with fields for first name, last name, username and password. It displays validation messages for invalid fields when the submit button is clicked. On submit the register() method is called if the form is valid.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <div class="col-md-6 col-md-offset-3">
        <h2>Register</h2>
        <form name="form" (ngSubmit)="f.form.valid && register()" #f="ngForm" novalidate>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
                <label for="firstName">First Name</label>
                <input type="text" class="form-control" name="firstName" [(ngModel)]="model.firstName" #firstName="ngModel" required />
                <div *ngIf="f.submitted && !firstName.valid" class="help-block">First Name is required</div>
            </div>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
                <label for="lastName">Last Name</label>
                <input type="text" class="form-control" name="lastName" [(ngModel)]="model.lastName" #lastName="ngModel" required />
                <div *ngIf="f.submitted && !lastName.valid" class="help-block">Last Name is required</div>
            </div>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
                <label for="username">Username</label>
                <input type="text" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
                <div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
            </div>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
                <label for="password">Password</label>
                <input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required />
                <div *ngIf="f.submitted && !password.valid" class="help-block">Password is required</div>
            </div>
            <div class="form-group">
                <button [disabled]="loading" class="btn btn-primary">Register</button>
                <img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
                <a [routerLink]="['/login']" class="btn btn-link">Cancel</a>
            </div>
        </form>
    </div>
     

    Angular 2 Register Component

    Path: /app/register/register.component.ts

    The register component has a single register() method that creates a new user with the user service when the register form is submitted.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import { Component } from '@angular/core';
    import { Router } from '@angular/router';
     
    import { AlertService, UserService } from '../_services/index';
     
    @Component({
        moduleId: module.id,
        templateUrl: 'register.component.html'
    })
     
    export class RegisterComponent {
        model: any = {};
        loading = false;
     
        constructor(
            private router: Router,
            private userService: UserService,
            private alertService: AlertService) { }
     
        register() {
            this.loading = true;
            this.userService.create(this.model)
                .subscribe(
                    data => {
                        // set success message and pass true paramater to persist the message after redirecting to the login page
                        this.alertService.success('Registration successful', true);
                        this.router.navigate(['/login']);
                    },
                    error => {
                        this.alertService.error(error);
                        this.loading = false;
                    });
        }
    }
     

    Angular 2 App Component Template

    Path: /app/app.component.html

    The app component template is the root component template of the application, it contains a router-outlet directive for displaying the contents of each view based on the current route, and an alert directive for displaying alert messages from anywhere in the system.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- main app container -->
    <div class="jumbotron">
        <div class="container">
            <div class="col-sm-8 col-sm-offset-2">
                <alert></alert>
                <router-outlet></router-outlet>
            </div>
        </div>
    </div>
     

    Angular 2 App Component

    Path: /app/app.component.ts

    The app component is the root component of the application, it defines the root tag of the app as <app></app> with the selector property.

    The moduleId property is set to allow a relative path to be used for the templateUrl.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { Component } from '@angular/core';
     
    @Component({
        moduleId: module.id,
        selector: 'app',
        templateUrl: 'app.component.html'
    })
     
    export class AppComponent { }
     

    Angular 2 App Module

    Path: /app/app.module.ts

    The app module defines the root module of the application along with metadata about the module. For more info about angular 2 modules check out this page on the official docs site.

    This is where the fake backend provider is added to the application, to switch to a real backend simply remove the providers located under the comment "// providers used to create fake backend".

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    import { NgModule }      from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule }    from '@angular/forms';
    import { HttpModule } from '@angular/http';
     
    // used to create fake backend
    import { fakeBackendProvider } from './_helpers/index';
    import { MockBackend, MockConnection } from '@angular/http/testing';
    import { BaseRequestOptions } from '@angular/http';
     
    import { AppComponent }  from './app.component';
    import { routing }        from './app.routing';
     
    import { AlertComponent } from './_directives/index';
    import { AuthGuard } from './_guards/index';
    import { AlertService, AuthenticationService, UserService } from './_services/index';
    import { HomeComponent } from './home/index';
    import { LoginComponent } from './login/index';
    import { RegisterComponent } from './register/index';
     
    @NgModule({
        imports: [
            BrowserModule,
            FormsModule,
            HttpModule,
            routing
        ],
        declarations: [
            AppComponent,
            AlertComponent,
            HomeComponent,
            LoginComponent,
            RegisterComponent
        ],
        providers: [
            AuthGuard,
            AlertService,
            AuthenticationService,
            UserService,
     
            // providers used to create fake backend
            fakeBackendProvider,
            MockBackend,
            BaseRequestOptions
        ],
        bootstrap: [AppComponent]
    })
     
    export class AppModule { }
     

    Angular 2 App Routing

    Path: /app/app.routing.ts

    The app routing file defines the routes of the application, each route contains a path and associated component. The home route is secured by passing the AuthGuard to the canActivate property of the route.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import { Routes, RouterModule } from '@angular/router';
     
    import { HomeComponent } from './home/index';
    import { LoginComponent } from './login/index';
    import { RegisterComponent } from './register/index';
    import { AuthGuard } from './_guards/index';
     
    const appRoutes: Routes = [
        { path: '', component: HomeComponent, canActivate: [AuthGuard] },
        { path: 'login', component: LoginComponent },
        { path: 'register', component: RegisterComponent },
     
        // otherwise redirect to home
        { path: '**', redirectTo: '' }
    ];
     
    export const routing = RouterModule.forRoot(appRoutes);
     

    Angular 2 Main (Bootstrap) File

    Path: /app/main.ts

    The main file is the entry point used by angular to launch and bootstrap the application.

    1
    2
    3
    4
    5
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
     
    import { AppModule } from './app.module';
     
    platformBrowserDynamic().bootstrapModule(AppModule);

    Angular 2 Development Consultant Sydney

    Feel free to drop me a line if you're looking for an Angular 2 development consultant in Sydney Australia, I also provide remote contracting services for clients outside Sydney.

    By Jason Watmore

    Tags: Angular 2, Login, Registration, Authentication and Authorization


  • 相关阅读:
    Java 中文数字转换为阿拉伯数字
    正则表达式转义符
    git .gitignore详解
    git 陷阱小记
    git log 附加命令归纳
    git 命令归纳版
    《Effective Java》 读书笔记(九)使用try-with-resources 语句替代try-finally
    架构设计 | 接口幂等性原则,防重复提交Token管理
    数据源管理 | OLAP查询引擎,ClickHouse集群化管理
    Java并发编程(04):线程间通信,等待/通知机制
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645269.html
Copyright © 2011-2022 走看看