In a real scenario, we usually delegate all the heavy lifting on an authentication service that wraps all the necessary tools for handling user login, logout, and sometimes authentication for granting access to protected areas of our application.
we will create a simplified version of such service and will put it in charge of handling user login along with the component we just created in the previous section. This service will also manage auth token persistence and provide methods to check if the user has access granted to secure pages.
Before jumping into the code, let’s summarize the minimum requirements this service must fulfil:
- We need its API to expose a method to handle user login
- User logout must be handled as well by a public method in this API
- A third method or property should inform if the user is logged in or not so they can proceed to secured pages
- Having an observable property informing of the current state of the active user for authentication will become handy to make the overall UI more reactive
With these specifications in mind, let’s build our ideal authentication service .
Since this service is component-agnostic and will have an impact on the whole application, we will store it in the services folder of our shared context, applying the naming conventions we already know and exposing it through the shared facade:
app/shared/services/authentication.service.ts
import { Injectable, EventEmitter } from '@angular/core'; @Injectable() export default class AuthenticationService { constructor() {} login({username, password}): Promise<boolean> {} logout(): Promise<boolean> {} static isAuthorized(): boolean {} }
app/shared/shared.ts
import Queueable from './interfaces/queueable'; import Task from './interfaces/task'; import FormattedTimePipe from './pipes/formatted-time.pipe'; import QueuedOnlyPipe from './pipes/queued-only.pipe'; import AuthenticationService from './services/authentication.service'; import SettingsService from './services/settings.service'; import TaskService from './services/task.service'; const SHARED_PIPES: any[] = [ FormattedTimePipe, QueuedOnlyPipe ]; const SHARED_PROVIDERS: any[] = [ AuthenticationService, SettingsService, TaskService ]; export { Queueable, Task, FormattedTimePipe, QueuedOnlyPipe, SHARED_PIPES, AuthenticationService, SettingsService, TaskService, SHARED_PROVIDERS };
As you can see in the resulting facade, the new service will become part of the SHARED_PROVIDERS
group token. Then, it will be available for our application injector, since this symbol is being declared in the providers array of our root component.