Cree una página de inicio de sesión simple usando Angular 8, 9 y autenticación HTTP
En este artículo, aprenderá cómo configurar una página de inicio de sesión simple utilizando Angular 8-9 y autenticación HTTP básica
Tutorial construido con Angular 8.0.2 y el CLI angular
CLI angular se utilizó para generar la estructura del proyecto base con el ng new
comando, la CLI también se usa para construir y servir la aplicación. Para obtener más información sobre la CLI de Angular, consulte https://angular.io/cli .
El estilo de la aplicación de ejemplo se realiza con Bootstrap 4.3, para obtener más información sobre Oreja ver https://getbootstrap.com/docs/4.3/getting-started/introduction/ .
Ejecución del ejemplo del tutorial de autenticación básica de Angular 8 localmente
- Instale NodeJS y NPM desde https://nodejs.org/en/download/ .
- Descargue o clone el código fuente del proyecto del tutorial de https://github.com/cornflourblue/angular-8-basic-authentication-example
- Instale todos los paquetes npm necesarios ejecutando
npm install
desde la línea de comando en la carpeta raíz del proyecto (donde se encuentra el package.json). - Inicie la aplicación ejecutando
npm start
desde el - línea de comando en la carpeta raíz del proyecto, esto construirá la aplicación
- y ejecutarlo automáticamente en el navegador en la URL
- http: // localhost: 4200.
NOTA: También puede ejecutar la aplicación directamente usando el CLI angular comando ng serve --open
. Para hacer esto, primero instale el CLI angular globalmente en su sistema con el comando npm install -g @angular/cli
.
Ejecución del ejemplo del tutorial con una API de backend real
los Angular 8 básico autenticación La aplicación de ejemplo utiliza un backend falso / simulado de forma predeterminada para que pueda ejecutarse en el navegador sin una api real. Para cambiar a una api de backend real, solo tiene que eliminar o comentar la línea debajo del comentario // provider used to create fake backend
ubicado en el /src/app/app.module.ts
expediente.
Estructura del proyecto del tutorial de Angular 8
La estructura de la aplicación y el código del tutorial sigue principalmente las recomendaciones de mejores prácticas en el Guía de estilo angular , con algunos de mis propios ajustes aquí y allá.
Cada función tiene su propia carpeta (inicio e inicio de sesión), otros códigos compartidos / comunes como servicios, modelos, ayudantes, etc. se colocan en carpetas con el prefijo de subrayado _
para diferenciarlos fácilmente y agruparlos en la parte superior de la estructura de carpetas.
El index.ts
Los archivos de cada carpeta son archivos de barril que agrupan los módulos exportados de una carpeta para que puedan importarse utilizando la ruta de la carpeta en lugar de la ruta completa del módulo y para permitir la importación de varios módulos en una sola importación (por ejemplo, import { AuthenticationService, UserService } from '../_services'
).
Alias de ruta @app
y @environments
han sido configurados en tsconfig.json ese mapa al /src/app
y /src/environments
directorios. Esto permite que las importaciones sean relativas a las carpetas de aplicaciones y entornos al prefijar las rutas de importación con alias en lugar de tener que usar rutas relativas largas (por ejemplo, import MyComponent from '../../../MyComponent'
).
Aquí están los archivos principales del proyecto que contienen la lógica de la aplicación, dejé algunos archivos que fueron generados por Angular CLI ng new
comando que no cambié.
- src
- aplicación
- _ayudadores
- auth.guard.ts
- interceptor.ts de autenticación básica
- error.interceptor.ts
- fake-backend.ts
- index.ts
- _modelos
- user.ts
- index.ts
- _servicios
- authentication.service.ts
- user.service.ts
- index.ts
- hogar
- home.component.html
- home.component.ts
- index.ts
- acceso
- login.component.html
- login.component.ts
- index.ts
- app.component.html
- app.component.ts
- app.module.ts
- app.routing.ts
- ambientes
- environment.prod.ts
- environment.ts
- index.html
- main.ts
- polyfills.ts
- styles.less
- package.json
- tsconfig.json
Auth Guard
Ruta: /src/app/_helpers/auth.guard.ts
La protección de autenticación es una protección de ruta angular que se utiliza para evitar que los usuarios no autenticados accedan a rutas restringidas, lo hace implementando el CanActivate
interfaz que permite al guardia decidir si una ruta se puede activar con el canActivate()
método. Si el método devuelve true
la ruta está activada (se permite continuar), de lo contrario, si el método devuelve false
la ruta está bloqueada.
El auth guard usa el servicio de autenticacion para comprobar si el usuario está conectado, si está conectado, devuelve true
desde el canActivate()
método, de lo contrario devuelve false
y redirige al usuario a la página de inicio de sesión.
Guardias de ruta angular se adjuntan a las rutas en la configuración del enrutador, esta protección de autenticación se utiliza en app.routing.ts para proteger la ruta de la página de inicio.
|_+_|Interceptor de autenticación básica
Ruta: /src/app/_helpers/basic-auth.interceptor.ts
los Autenticación básica Interceptor intercepta las solicitudes http de la aplicación para agregar credenciales de autenticación básicas al encabezado de autorización si el usuario ha iniciado sesión.
Se implementa utilizando la clase HttpInterceptor incluida en HttpClientModule, al extender la clase HttpInterceptor puede crear un interceptor personalizado para modificar las solicitudes http antes de que se envíen al servidor.
Los interceptores HTTP se agregan a la canalización de solicitudes en la sección de proveedores de import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AuthenticationService } from '@app/_services'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor( private router: Router, private authenticationService: AuthenticationService ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { const currentUser = this.authenticationService.currentUserValue; if (currentUser) { // logged in so return true return true; } // not logged in so redirect to login page with the return url this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); return false; } }
expediente.
Interceptor de errores Http
Ruta: /src/app/_helpers/error.interceptor.ts
es omi coin una buena inversión
El Interceptor de errores intercepta las respuestas http de la API para verificar si hubo algún error. Si hay una respuesta 401 no autorizada, el usuario se desconecta automáticamente de la aplicación, todos los demás errores se vuelven a enviar al servicio de llamada para que se muestre una alerta con el error en la pantalla.
Se implementa utilizando la clase HttpInterceptor incluida en HttpClientModule, al extender la clase HttpInterceptor puede crear un interceptor personalizado para capturar todas las respuestas de error del servidor en una sola ubicación.
Los interceptores HTTP se agregan a la canalización de solicitudes en la sección de proveedores de _app.module.ts_
expediente.
Proveedor de backend falso
Ruta: /src/app/_helpers/fake-backend.ts
Para ejecutar y probar la aplicación Angular sin una API de backend real, el ejemplo utiliza un backend falso que intercepta las solicitudes HTTP del Aplicación angular y enviar respuestas falsas. Esto lo hace una clase que implementa Angular import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { AuthenticationService } from '@app/_services'; @Injectable() export class BasicAuthInterceptor implements HttpInterceptor { constructor(private authenticationService: AuthenticationService) { } intercept(request: HttpRequest, next: HttpHandler): Observable> { // add authorization header with basic auth credentials if available const currentUser = this.authenticationService.currentUserValue; if (currentUser && currentUser.authdata) { request = request.clone({ setHeaders: { Authorization: `Basic ${currentUser.authdata}` } }); } return next.handle(request); } }
interfaz, para obtener más información sobre interceptores HTTP angulares, consulte https://angular.io/api/common/http/HttpInterceptor
El backend falso contiene un app.module.ts
función que verifica si la solicitud coincide con una de las rutas falsas en la declaración de cambio, en este momento esto incluye import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { AuthenticationService } from '@app/_services'; @Injectable() export class ErrorInterceptor implements HttpInterceptor { constructor(private authenticationService: AuthenticationService) { } intercept(request: HttpRequest, next: HttpHandler): Observable> { return next.handle(request).pipe(catchError(err => { if (err.status === 401) { // auto logout if 401 response returned from api this.authenticationService.logout(); location.reload(true); } const error = err.error.message || err.statusText; return throwError(error); })) } }
solicitudes al HttpInterceptor
ruta para manejar la autenticación, y handleRoute
solicitudes al POST
ruta para obtener todos los usuarios.
Las solicitudes a la ruta de autenticación son manejadas por el /users/authenticate
función que comprueba el nombre de usuario y la contraseña con una matriz de GET
codificados de forma rígida. Si el nombre de usuario y la contraseña son correctos, entonces un /users
La respuesta se devuelve con los detalles del usuario, de lo contrario, un authenticate()
se devuelve la respuesta.
Las solicitudes a la ruta de obtención de usuarios son manejadas por el users
función que comprueba si el usuario ha iniciado sesión llamando al nuevo ok
función auxiliar. Si el usuario está registrado en un error
respuesta con el conjunto getUsers()
se devuelve una matriz, de lo contrario un isLoggedIn()
La respuesta se devuelve llamando al nuevo ok()
función auxiliar.
Si la solicitud no coincide con ninguna de las rutas falsas, se pasa como una solicitud HTTP real a la API de backend.
|_+_|Modelo de usuario
Ruta: /src/app/_models/user.ts
El modelo de usuario es una clase pequeña que define las propiedades de un usuario.
|_+_|Servicio de autenticacion
Ruta: /src/app/_services/authentication.service.ts
El servicio de autenticación se utiliza para iniciar sesión y cerrar sesión en la aplicación Angular, notifica a otros componentes cuando el usuario inicia sesión y cierra sesión, y permite acceder al usuario actualmente conectado.
Los sujetos y observables de RxJS se utilizan para almacenar el objeto de usuario actual y notificar a otros componentes cuando el usuario inicia sesión y sale de la aplicación. Los componentes angulares pueden users
al público 401 Unauthorized
propiedad para ser notificado de los cambios, y las notificaciones se envían cuando el unauthorized()
se llama al método en el import { Injectable } from '@angular/core'; import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Observable, of, throwError } from 'rxjs'; import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators'; import { User } from '@app/_models'; const users: User[] = [{ id: 1, username: 'test', password: 'test', firstName: 'Test', lastName: 'User' }]; @Injectable() export class FakeBackendInterceptor implements HttpInterceptor { intercept(request: HttpRequest, next: HttpHandler): Observable> { const { url, method, headers, body } = request; // wrap in delayed observable to simulate server api call return of(null) .pipe(mergeMap(handleRoute)) .pipe(materialize()) // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648) .pipe(delay(500)) .pipe(dematerialize()); function handleRoute() { switch (true) { case url.endsWith('/users/authenticate') && method === 'POST': return authenticate(); case url.endsWith('/users') && method === 'GET': return getUsers(); default: // pass through any requests not handled above return next.handle(request); } } // route functions function authenticate() { const { username, password } = body; const user = users.find(x => x.username === username && x.password === password); if (!user) return error('Username or password is incorrect'); return ok({ id: user.id, username: user.username, firstName: user.firstName, lastName: user.lastName }) } function getUsers() { if (!isLoggedIn()) return unauthorized(); return ok(users); } // helper functions function ok(body?) { return of(new HttpResponse({ status: 200, body })) } function error(message) { return throwError({ error: { message } }); } function unauthorized() { return throwError({ status: 401, error: { message: 'Unauthorised' } }); } function isLoggedIn() { return headers.get('Authorization') === `Basic ${window.btoa('test:test')}`; } } } export let fakeBackendProvider = { // use fake backend in place of Http service for backend-less development provide: HTTP_INTERCEPTORS, useClass: FakeBackendInterceptor, multi: true };
y export class User { id: number; username: string; password: string; firstName: string; lastName: string; authdata?: string; }
métodos, pasando el argumento a cada suscriptor. El RxJS subscribe()
es un tipo especial de Asunto que mantiene el valor actual y lo emite a los nuevos suscriptores tan pronto como se suscriben, mientras que los Asignativos normales no almacenan el valor actual y solo emiten valores que se publican después de que se crea una suscripción.
El currentUser: Observable
El método envía las credenciales del usuario a la API a través de una solicitud HTTP POST para la autenticación. Si tiene éxito, los datos de autenticación básica del usuario (nombre de usuario y contraseña codificados en base64) se agregan al objeto de usuario y se almacenan en localStorage para mantener al usuario conectado entre actualizaciones de página. A continuación, el objeto de usuario se publica para todos los suscriptores con la llamada a this.currentUserSubject.next()
.
El interceptor de autenticación básico anterior utiliza los datos de autenticación básicos para establecer el encabezado de autorización de las solicitudes http realizadas para asegurar los puntos finales de la API.
El login()
del servicio inicializa el logout()
con el objeto currentUser de localStorage que permite al usuario permanecer conectado entre actualizaciones de página o después de cerrar el navegador. El público BehaviorSubject
a continuación, la propiedad se establece en login()
que permite que otros componentes se suscriban al this.currentUserSubject.next(user);
Se puede observar, pero no les permite publicar en constructor()
, por lo que iniciar y cerrar sesión en la aplicación solo se puede realizar a través del servicio de autenticación.
El currentUserSubject
getter permite otros componentes de una manera fácil de obtener el valor del usuario actualmente conectado sin tener que suscribirse al currentUser
Observable.
El this.currentUserSubject.asObservable();
El método elimina el objeto de usuario actual del almacenamiento local y publica currentUser
al currentUserSubject
para notificar a todos los suscriptores que el usuario se ha desconectado.
Servicio al usuario
Ruta: /src/app/_services/user.service.ts
El servicio de usuario contiene un método para obtener todos los usuarios de la API, lo incluí para demostrar el acceso a un punto final de API seguro con el encabezado de autorización http establecido después de iniciar sesión en la aplicación, el encabezado de autenticación se configura automáticamente con credenciales de autenticación básicas por el básico interceptor de autenticación. El punto final seguro en el ejemplo es uno falso implementado en el proveedor de backend falso.
nombre de usuario y contraseña de minecraft|_+_|
Plantilla de componente de inicio
Ruta: /src/app/home/home.component.html
La plantilla del componente de inicio contiene sintaxis de plantilla html y angular 8 para mostrar un mensaje de bienvenida simple y una lista de usuarios desde un punto final seguro de la API.
|_+_|Componente de la casa
Ruta: /src/app/home/home.component.ts
El componente de inicio define un componente angular de 8 que obtiene a todos los usuarios del servicio de usuario y los pone a disposición de la plantilla a través de un currentUserValue
propiedad de matriz.
Plantilla de componente de inicio de sesión
Ruta: /src/app/login/login.component.html
La plantilla del componente de inicio de sesión contiene un formulario de inicio de sesión con campos de nombre de usuario y contraseña. Muestra mensajes de validación para campos no válidos cuando se hace clic en el botón Enviar. El evento de envío de formulario está vinculado a currentUser
método del componente de inicio de sesión.
Componente de inicio de sesión
Ruta: /src/app/login/login.component.ts
El componente de inicio de sesión utiliza el servicio de autenticación para iniciar sesión en la aplicación. Si el usuario ya ha iniciado sesión, se le redirige automáticamente a la página de inicio.
El logout()
El objeto define los controles y validadores del formulario, y se utiliza para acceder a los datos ingresados en el formulario. FormGroup es parte del módulo Angular Reactive Forms y está vinculado a la plantilla de inicio de sesión anterior con null
directiva.
Plantilla de componente de aplicación
Ruta: /src/app/app.component.html
La plantilla del componente de la aplicación es la plantilla del componente raíz de la aplicación, contiene la barra de navegación principal que solo se muestra para los usuarios autenticados y una directiva de salida del enrutador para mostrar el contenido de cada vista en función de la ruta / ruta actual.
|_+_|Componente de la aplicación
Ruta: /src/app/app.component.ts
El componente de la aplicación es el componente raíz de la aplicación, define la etiqueta raíz de la aplicación como 'con la propiedad de selector de currentUserSubject
decorador.
Se suscribe a la import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { environment } from '@environments/environment'; import { User } from '@app/_models'; @Injectable({ providedIn: 'root' }) export class AuthenticationService { private currentUserSubject: BehaviorSubject; public currentUser: Observable; constructor(private http: HttpClient) { this.currentUserSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('currentUser'))); this.currentUser = this.currentUserSubject.asObservable(); } public get currentUserValue(): User { return this.currentUserSubject.value; } login(username: string, password: string) { return this.http.post(`${environment.apiUrl}/users/authenticate`, { username, password }) .pipe(map(user => { // store user details and basic auth credentials in local storage to keep user logged in between page refreshes user.authdata = window.btoa(username + ':' + password); localStorage.setItem('currentUser', JSON.stringify(user)); this.currentUserSubject.next(user); return user; })); } logout() { // remove user from local storage to log user out localStorage.removeItem('currentUser'); this.currentUserSubject.next(null); } }
observable en el servicio de autenticación para que pueda mostrar / ocultar de forma reactiva la barra de navegación principal cuando el usuario inicia / cierra sesión en la aplicación. No me preocupé por cancelar la suscripción al observable aquí porque es el componente raíz de la aplicación, la única vez que se destruirá el componente es cuando se cierre la aplicación, lo que también destruiría las suscripciones.
El componente de la aplicación contiene un import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { environment } from '@environments/environment'; import { User } from '@app/_models'; @Injectable({ providedIn: 'root' }) export class UserService { constructor(private http: HttpClient) { } getAll() { return this.http.get(`${environment.apiUrl}/users`); } }
método que se llama desde el enlace de cierre de sesión en la barra de navegación principal de arriba para cerrar la sesión del usuario y redirigirlo a la página de inicio de sesión.
Módulo de aplicación
Ruta: /src/app/app.module.ts
El módulo de la aplicación define el módulo raíz de la aplicación junto con los metadatos sobre el módulo. Para obtener más información sobre los módulos angulares 8, consulte esta página en el sitio oficial de documentos.
Aquí es donde se agrega el proveedor de backend falso a la aplicación, para cambiar a un backend real, simplemente elimine los proveedores ubicados debajo del comentario #### You're logged in with Angular 8 & Basic HTTP Authentication!! ###### Users from secure api end point {{user.firstName}} {{user.lastName}}
.
Módulo de enrutamiento de aplicaciones
Ruta: /src/app/app.routing.ts
El enrutamiento para la aplicación Angular se configura como una matriz de users
, cada componente se asigna a una ruta para que el enrutador angular sepa qué componente mostrar en función de la URL en la barra de direcciones del navegador. La ruta de origen se asegura pasando el AuthGuard al import { Component } from '@angular/core'; import { first } from 'rxjs/operators'; import { User } from '@app/_models'; import { UserService } from '@app/_services'; @Component({ templateUrl: 'home.component.html' }) export class HomeComponent { loading = false; users: User[]; constructor(private userService: UserService) { } ngOnInit() { this.loading = true; this.userService.getAll().pipe(first()).subscribe(users => { this.loading = false; this.users = users; }); } }
propiedad de la ruta.
El onSubmit()
se pasa a la matriz Username: test Password: test #### Angular 8 Basic Auth Login Example Username Username is required Password Password is required Login {{error}}
método que crea un módulo de enrutamiento con todas las rutas de la aplicación configuradas, y también incluye todos los proveedores y directivas de enrutadores angulares, como la directiva `` directive. Para obtener más información sobre navegación y enrutamiento angular, consulte https://angular.io/guide/router .
Configuración del entorno de producción
Ruta: /src/environments/environment.prod.ts
La configuración del entorno de producción contiene las variables necesarias para ejecutar la aplicación en producción. Esto le permite crear la aplicación con una configuración diferente para cada entorno diferente (por ejemplo, producción y desarrollo) sin actualizar el código de la aplicación.
Cuando crea la aplicación para producción con el comando loginForm: FormGroup
, la salida [formGroup]='loginForm'
se reemplaza por import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { first } from 'rxjs/operators'; import { AuthenticationService } from '@app/_services'; @Component({ templateUrl: 'login.component.html' }) export class LoginComponent implements OnInit { loginForm: FormGroup; loading = false; submitted = false; returnUrl: string; error = ''; constructor( private formBuilder: FormBuilder, private route: ActivatedRoute, private router: Router, private authenticationService: AuthenticationService ) { // redirect to home if already logged in if (this.authenticationService.currentUserValue) { this.router.navigate(['/']); } } ngOnInit() { this.loginForm = this.formBuilder.group({ username: ['', Validators.required], password: ['', Validators.required] }); // get return url from route parameters or default to '/' this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; } // convenience getter for easy access to form fields get f() { return this.loginForm.controls; } onSubmit() { this.submitted = true; // stop here if form is invalid if (this.loginForm.invalid) { return; } this.loading = true; this.authenticationService.login(this.f.username.value, this.f.password.value) .pipe(first()) .subscribe( data => { this.router.navigate([this.returnUrl]); }, error => { this.error = error; this.loading = false; }); } }
.
Configuración del entorno de desarrollo
Ruta: /src/environments/environment.ts
La configuración del entorno de desarrollo contiene las variables necesarias para ejecutar la aplicación en desarrollo.
Se accede a la configuración del entorno importando el objeto de entorno en cualquier servicio de componente angular con la línea Home Logout
y accediendo a propiedades en el @Component()
objeto, consulte el servicio de usuario para ver un ejemplo.
Archivo HTML de índice principal
Ruta: /src/index.html
El archivo index.html principal es la página inicial cargada por el navegador que inicia todo. Angular CLI (con Webpack bajo el capó) agrupa todos los archivos javascript compilados y los inyecta en el cuerpo de la página index.html para que el navegador pueda cargar y ejecutar los scripts.
|_+_|Archivo principal (Bootstrap)
Ruta: /src/main.ts
El archivo principal es el punto de entrada utilizado por angular para iniciar y arrancar la aplicación.
|_+_|Polyfills
Ruta: /src/polyfills.ts
Algunas funciones utilizadas por Angular 8 aún no son compatibles de forma nativa con todos los navegadores principales, los polyfills se utilizan para agregar soporte para funciones cuando sea necesario para que su aplicación Angular 8 funcione en todos los navegadores principales.
Este archivo es generado por la CLI de Angular al crear un nuevo proyecto con currentUser
comando, he excluido los comentarios en el archivo por brevedad.
color de borde de transición css|_+_|
Estilos globales LESS / CSS
Ruta: /src/styles.less
El archivo de estilos globales contiene estilos LESS / CSS que se aplican globalmente en toda la aplicación.
|_+_|npm package.json
Ruta: /package.json
El archivo package.json contiene información de configuración del proyecto, incluidas las dependencias de paquetes que se instalan cuando ejecuta logout()
. La documentación completa está disponible en el sitio web de npm docs .
TypeScript tsconfig.json
Ruta: /tsconfig.json
El archivo tsconfig.json configura cómo el compilador de TypeScript convertirá TypeScript en JavaScript, lo que el navegador entiende. Más información está disponible en el Documentos de TypeScript .
La mayor parte del archivo no ha cambiado desde que fue generado por el CLI angular , solo el import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { AuthenticationService } from './_services'; import { User } from './_models'; @Component({ selector: 'app', templateUrl: 'app.component.html' }) export class AppComponent { currentUser: User; constructor( private router: Router, private authenticationService: AuthenticationService ) { this.authenticationService.currentUser.subscribe(x => this.currentUser = x); } logout() { this.authenticationService.logout(); this.router.navigate(['/login']); } }
propiedad ha sido agregada al mapa // provider used to create fake backend
y import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; // used to create fake backend import { fakeBackendProvider } from './_helpers'; import { AppComponent } from './app.component'; import { appRoutingModule } from './app.routing'; import { BasicAuthInterceptor, ErrorInterceptor } from './_helpers'; import { HomeComponent } from './home'; import { LoginComponent } from './login'; @NgModule({ imports: [ BrowserModule, ReactiveFormsModule, HttpClientModule, appRoutingModule ], declarations: [ AppComponent, HomeComponent, LoginComponent ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: BasicAuthInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, // provider used to create fake backend fakeBackendProvider ], bootstrap: [AppComponent] }) export class AppModule { }
al Routes
y canActivate
directorios. Esto permite que las importaciones sean relativas a las carpetas de aplicaciones y entornos al prefijar las rutas de importación con alias en lugar de tener que usar rutas relativas largas (por ejemplo, Routes
).
El código del tutorial está disponible en GitHub
#angular # desarrollo web #seguridad # angular8 # angular9