Back to the service class, we imported the Injectable decorator. As you know, we will need it if we want our AuthService class to be automatically instantiated and injected as a singleton in our components by Angular (in case our class requires its own dependencies in the future). We also import the EventEmitter class, which we will cover later in this section.

In the body of the AuthenticationService class, we have defined an empty constructor and three methods with no implementation (one of them being static). While the names give a very good hint of the purpose of each method, perhaps the last one requires some more elaboration: The isAuthorized() method will inform if the user has permissions to access secured pages. The reason why it is static is because we will need to use it in some areas where Angular’s dependency injection machinery cannot reach so no automatic provider injection is available.

Our first requirement was to provide a public method to handle user login. Let’s go for it. Get back to the AuthenticationService module and extend the login method with the following implementation:

app/shared/services/authentication.service.ts

login({username, password}): Promise<boolean> {
  return new Promise(resolve => {
    let validCredentials: boolean = false;

    // @NOTE: In a real scenario this check 
    // should be performed against a web service:
    if (username === '[email protected]' && 
        password === 'letmein') {
          validCredentials = true;
          window.sessionStorage.setItem('token', 'eyJhbGciOi');
    }

    resolve(validCredentials);
  });
}

, we are not submitting data for validation to a remote web service although we should definitely do. you should never implement user validation this way. Having said that, let’s review this implementation. In the first place, there is something that draws our attention: the returning type. This method is supposed to return a Promise and there is a good reason for that. Usually, you would also want to implement an async HTTP connection to a remote service so you can send the user credentials and wait for a response. Hence, we use the asynchronous interface in the form of a returning Promise, which resolves to a Boolean value informing if the credentials provided are good to access the system or not. On the other hand, the method signature is not an annotated argument, but a deconstructed object informing that this method will expect any type or object in its payload containing both username and password properties. Last but not least, right after conducting our fake user validation, we store a random token onto the user’s browser using the browser’s own session storage layer. This is a common way of handling authentication and user session persistence nowadays, with the sole difference that the token is usually sent in the body of the server response and thereafter is sent back in the request headers on every information request made to the server.