Angular. Implementando Login.
By ercobo | Published | No hay comentarios
Hasta este momento hemos tenido siempre visible nuestra app angular con la parte publica (la que va a ver cualquier usuario que entre a la app).
¿Qué ocurre si vamos a implementar una administración?
Bueno, pues es el momento de empezar a separar cosas y usar las rutas de Angular para el funcionamiento. Lo que vamos a hacer es separar nuestra app, de momento, en tres rutas: «client» (para los visitantes), «login», para el formulario de entrada a la administración, y «admin» para la administración en si.
Para ello, hay que modificar un poco nuestra aplicación.
Comenzamos por crear un nuevo modulo con ng generate module routes. Con esto generaremos un nuevo archivo en el que vamos a colocar la logica de nuestras rutas de aplicación para que pueda funcionar.
A partir de aquí, tendremos que rellenar todos los campos para que las rutas sean reconocidas y utilizadas en nuestra app. Así que vamos por pasos:
- routes\routes.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; import { MainComponent } from './../admin/main/main.component'; import { LoginComponent } from './../common/login/login.component'; import { IndexComponent } from './../frontend/index/index.component'; // - Routes instead of RouteConfig // - RouterModule instead of provideRoutes const routes: Routes = [ { path: 'admin', component: MainComponent, }, { path: 'login', component: LoginComponent }, { path: 'client', component: IndexComponent, }, { path: '', redirectTo: 'client', pathMatch: 'full' }, ]; // - Updated Export export const routing = RouterModule.forRoot(routes); @NgModule({ imports: [ CommonModule ], declarations: [] }) export class RoutesModule { } |
- app.component.html. Este únicamente necesita estar compuesto por
1 - main.ts. Aquí indicaremos nuestro modulo de rutas y que se utilicen en el inicio del modulo de la app.
1 2 3 4 5 6 7 8 9 10 11 |
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { routing } from './app/routes/routes.module'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule, [routing]); |
- app.module.ts. Aqui tenemos que declarar las rutas e importarlas para que sean usadas correctamente. Sino habrá errores.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { routing } from './routes/routes.module'; // ROUTING HERE! import { AppComponent } from './app.component'; import { NavComponent } from './frontend/nav/nav.component'; import { DishesComponent } from './frontend/dishes/dishes.component'; import { DrinksComponent } from './frontend/drinks/drinks.component'; import { WinesComponent } from './frontend/wines/wines.component'; import { ContactComponent } from './frontend/contact/contact.component'; import { FooterComponent } from './frontend/footer/footer.component'; import { LoginComponent } from './common/login/login.component'; import { MainComponent } from './admin/main/main.component'; import { IndexComponent } from './frontend/index/index.component'; @NgModule({ declarations: [ AppComponent, NavComponent, DishesComponent, DrinksComponent, WinesComponent, ContactComponent, FooterComponent, LoginComponent, MainComponent, IndexComponent, ], imports: [ BrowserModule, routing, FormsModule, HttpModule ], providers: [], bootstrap: [ AppComponent ] }) export class AppModule { } |
Ahora generaremos los componentes que formarán el login y la entrada a la administración.
- ng generate component common\login. Con esto generaremos el componente del formulario de login.
- ng generate component admin\main. Con esto generamos el componente de entrada a la administración.
- ng generate service services\login. Con esto generaremos el servicio que se encargara de procesar los datos.
Y finalmente los poblaremos. De momento en la clase login está una clase «User» con los datos a pelo, en otra entrega utilizaremos un servicio para consumir los datos de la API que creamos con Laravel para hacer el login.
- login.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; export class User { constructor( public email: string, public password: string) { } } var users = [ new User('admin@admin.com','adm9'), new User('user1@gmail.com','a23') ]; @Injectable() export class LoginService { constructor( private _router: Router){} logout() { localStorage.removeItem("user"); this._router.navigate(['login']); } login(user){ var authenticatedUser = users.find(u => u.email === user.email); if (authenticatedUser && authenticatedUser.password === user.password){ localStorage.setItem("user", authenticatedUser.email); this._router.navigate(['admin']); return true; } return false; } checkCredentials(){ if (localStorage.getItem("user") === null){ this._router.navigate(['login']); } } } |
- login.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { Component, ElementRef, OnInit } from '@angular/core'; import {LoginService, User} from '../../services/login.service'; @Component({ selector: 'app-login', providers: [LoginService], templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { public user = new User('',''); public errorMsg = ''; constructor(private _service:LoginService) { } login() { if(!this._service.login(this.user)){ this.errorMsg = 'Failed to login'; } } ngOnInit() { } } |
- login.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Welcome {{errorMsg}} |
- main.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import { Component, OnInit } from '@angular/core'; import {LoginService, User} from '../../services/login.service'; @Component({ selector: 'app-login', providers: [LoginService], templateUrl: './main.component.html', styleUrls: ['./main.component.css'] }) export class MainComponent implements OnInit { constructor( private _service:LoginService){} ngOnInit(){ this._service.checkCredentials(); } logout() { this._service.logout(); } } |
- main.component.html
1 2 3 4 5 6 7 |
Con todos estos pasos, si comprobamos en nuestro navegador (teniendo encendido el servidor de angular de desarrollo, claro, con npm start), podremos ver que las rutas funcionan.
La ruta raíz («/» o » «) nos redirige automaticamente a la parte cliente (lo que hemos estado personalizando hasta ahora).
La ruta de administración («admin») nos redirige al formulario de login (ruta «login») si no nos hemos autentifcado, y nos muestra el mensaje de autenticación correcta y el link de logout.
Y con esto estamos en condiciones de ir desarrollando tanto la administración como la parte cliente.
En proximas entradas iremos viendo componentes, servicios y datos necesarios. Tambien volveremos a Laravel cuando haya detalles que impliquen nuevas situaciones con la API.
Muchas gracias por seguir hasta aquí 🙂
Actualizacion: una cosa más, para que funcione en el servidor apache, una vez compilada la web con ng build --prod es necesario que exista un archivo .htaccess con el siguiente contenido. Sino, las rutas no funcionaran:
1 2 3 4 5 6 |
RewriteEngine on RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^(.*) /index.html [NC,L] |