# 3.6: Improving Authentication

Right now, when we check to see if a user is logged in - we're only checking if there is an item in their local storage with the key 'token'.

As explained previously, this isn't entirely helpful for us. Is it invalid or expired? We don't know.

To help us improve our login and register method, we'll use a library for this provided by `Auth0` called `angular2-jwt`.

[Look over the docs if you'd like.](https://github.com/auth0/angular2-jwt)

In the docs, it lists the 'key features' of the library:

* Send a JWT on a per-request basis using the explicit AuthHttp class
* Decode a JWT from your Angular 2 app
* Check the expiration date of the JWT
* Conditionally allow route navigation based on JWT status

Sounds perfect!

## Installing and Configuring angular2-jwt

Make sure you are in the root folder of your `SPA` project and run the following command:

```
npm install @auth0/angular-jwt --save
```

Next, in our `app.module.ts` file, we'll import the library

```typescript
import { JwtModule } from '@auth0/angular-jwt';

//  ...

import: [
    //  ...
    JwtModule.forRoot({
      config: {
        tokenGetter: () => {
          return localStorage.getItem('token');
        },
        whitelistedDomains: ['localhost:5000']
      }
    })
]
```

## Updating loggedIn() method

In our `auth.service.ts` class, let's start by injecting the `JwtHelperService` provided by the library into our constructor.

```typescript
constructor(private _http: HttpClient,
            private _jwtHelperService: JwtHelperService) { }
```

Update the method in our service to check if a user has an unexpired token or not:

```typescript
loggedIn() {
    const token = this._jwtHelperService.tokenGetter();

    if (!token) {
        return false;
    }

    return !this._jwtHelperService.isTokenExpired(token);
}
```

## Decoding the token

Next, we'll add a property to hold the information in the token and the JwtHelper.

```typescript
decodedToken: any;
```

Update the `login()` method to use the jwtHelperService:

```typescript
login(model: any) {
    return this._http.post<AuthUser>(this.baseUrl + 'login', model, { headers: new HttpHeaders()
        .set('Content-Type', 'application/json') })
        .map(user => {
        if (user) {
            localStorage.setItem('token', user.tokenString);
            this.decodedToken = this._jwtHelperService.decodeToken(user.tokenString);   // <--- Added
            this.userToken = user.tokenString;
        }
        });
}
```

## Displaying the Username in the Nav

In the `nav.component.html`, let's use the `AuthService` to display the username when a user is logged in:

What we currently have:

```markup
Welcome, user!
```

Let's change it to:

```markup
Welcome, {{ authService.decodedToken?.unique_name }}!
```

The `decodedToken?` has a conditional null operator. If the page loads and it can't find this - it won't crash.

## Retrieving User Information ASAP

Right now, if we're logged in and then refresh the page - we lose our username in the navbar and our information.

Instead of just loading the information in the navbar, we'll try loading all user information as soon as the root component of the application is initialized (before the nav component).

In `app.component.ts`, update it to the following:

```typescript
export class AppComponent implements OnInit {
  constructor(
    private _authService: AuthService,
    private _jwtHelperService: JwtHelperService) {}

  ngOnInit() {
    const token = localStorage.getItem('token');
    const user: User = JSON.parse(localStorage.getItem('user'));

    if (token) {
      this._authService.decodedToken = this._jwtHelperService.decodeToken(token);
    }
  }
}
```

Now, we should be able to refresh the page without losing our status and information.

## Testing

Open up your browser, and try logging in!

![LoginNav](/files/-LEoXDZ_aiIuVABfBYc_)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eleven-fifty-academy.gitbook.io/dotnet-302-core/3-client-side-login-and-register/3.6-improving-authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
