3.2: Client-side Login

Add User and AuthUser models

  1. In your app folder, create a new folder called models.

  2. Add a new file called User.ts with the following code:

export interface User {
    id: number;
    username: string;
}
  1. Then add another file called AuthUser.ts

import { User } from './User';

export interface AuthUser {
    tokenString: string;
    user: User;
}

Import HttpClient

  1. In your app.module.ts add an import for the HttpClientModule after the BrowserModule:

import { HttpClientModule } from '@angular/common/http';

// ...
    imports: [
        BrowserModule,
        // import HttpClientModule after BrowserModule.
        HttpClientModule,
    ],

Angular AuthService

  1. In the project root of your SPA project run this command to generate a services folder and an auth.service.ts:

ng g s services/auth --no-spec
  1. In your new auth.service.ts file - import the HttpClient, HttpHeaders, our AuthUser, and the rxjs map operator

    1. Also, inject the HttpClient into the constructor. See the code below:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AuthUser } from '../models/AuthUser';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {
  constructor(private _http: HttpClient) { }
}
  1. Add a property called baseUrl set to the auth endpoint and a property called userToken of type any:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AuthUser } from '../models/AuthUser';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {
  baseUrl = 'http://localhost:5000/api/auth/';
  userToken: any;

  constructor(private _http: HttpClient) { }
}
  1. Next, let's go ahead and register our service in app.module.ts in the providers array:

import { AuthService } from './services/auth.service';

// ...

  providers: [
    AuthService
  ],

Login Method

  1. Now, we're ready to write our login() method in auth.service.ts: <!-- ```typescript login(model: any) { return this._http.post(this.baseUrl + 'login', model, { headers: new HttpHeaders() .set('Content-Type', 'application/json') }) .map(user => { if (user) { localStorage.setItem('token', user.tokenString); this.userToken = user.tokenString; } }); }

    <!-- The code below functions in rxjs version 6 -->
    ```typescript
    login(model: any) {
     return this._http.post<AuthUser>(this.baseUrl + 'login', model, {
       headers: new HttpHeaders()
         .set('Content-Type', 'application/json')})
         .pipe(map(user => {
           if (user) {
             console.log('this works');
             localStorage.setItem('token', user.tokenString);
             this.userToken = user.tokenString;
           }
         }));
    }

    Using the AuthService in our Nav Component

  2. In the nav.component.ts file, inject the AuthService into the constructor. We'll make it public here because we'll use it in the template.

  3. Modify the login() method to use our AuthService.

  4. We'll still log our result to the console (and also an error message) for testing purposes.

constructor(public authService: AuthService) { }

ngOnInit() {
}

login() {
    this.authService.login(this.model).subscribe(data => {
        console.log('logged in successfully');
    }, error => {
        console.log('Failed to login');
    });
}

Testing the Login Method

We need to start up our .API project and our SPA project. Preferences may vary - you can decide between the built-in terminal in VS Code or using a separate terminal.

Navigate to your two projects and start up the servers

dotnet watch run
ng serve

With your browser's console open, enter an actual username and password that you know is saved to your database.

You should get the logged in successfully message:

Now, navigate to the network tab in your developer tools.

You should see the 200 Ok response.

If you're using Google Chrome - click on the Application tab and then Local Storage and verify that our token is being stored in the browser's storage:

Chrome:

If you're using Firefox, click the Storage tab and then Local Storage:

Firefox:

Nice job! Logging in works!

Last updated