0% encontró este documento útil (0 votos)
241 vistas

Laravel - Angular API REST

El documento describe el proceso de creación de una API RESTful para gestionar escuelas profesionales utilizando Laravel y Angular. Se implementan operaciones CRUD (crear, leer, actualizar, eliminar) para la tabla "schools" en el backend de Laravel y se consume la API en una aplicación frontend de Angular para listar, crear y editar escuelas. También se agrega autenticación mediante JWT para proteger los puntos finales de la API.
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
241 vistas

Laravel - Angular API REST

El documento describe el proceso de creación de una API RESTful para gestionar escuelas profesionales utilizando Laravel y Angular. Se implementan operaciones CRUD (crear, leer, actualizar, eliminar) para la tabla "schools" en el backend de Laravel y se consume la API en una aplicación frontend de Angular para listar, crear y editar escuelas. También se agrega autenticación mediante JWT para proteger los puntos finales de la API.
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 16

https://bit.

ly/3MQ4KVi

1. Crearemos el API REST sobre el proyecto de SiSChampions2022


https://github.com/AngelDX/SisChampions2022
http://champions-fia.herokuapp.com/

2. Trabajaremos sobre la tabla schools

3. CRUD API REST


-Creamos un controlador:

Si queremos agregar los métodos usamos --resource


-En routes/api.php

Podemos ver la lista de rutas con: php artisan route:list


-Creamos un form request para las validaciones POST

-1-
https://bit.ly/3MQ4KVi

- En app/Http/Controllers/SchoolController.php

4. Probando los servicios con POSTMAN


Petición GET

-2-
https://bit.ly/3MQ4KVi

Petición POST

Es necesario configurar como $fillable o $guarded en el modelo para inserciones


masivas

-3-
https://bit.ly/3MQ4KVi

Petición PUT

Petición Delete

*Actividad implemente los servicios para la tabla places

5. CREAMOS PROYECTO ANGULAR


Verificar que se tiene instalado Node y el cliente de angular
npm install @angular/cli -g
Creamos los componentes:

-4-
https://bit.ly/3MQ4KVi

Creamos el servicio

Creamos el modelo

6. LISTAR
Primero an app.models agregar las librerías que usaremos

En la class model school

En el servicio:
Inyectamos Http para usar los métodos get, post put y delete

Declaramos la base url del rest api

Creamos el método para obtener la lista

En list-school.component.ts
Creamos una variable para obtener la lista del servicio y pasar al template
y también inyectamos el servicio usando el constructor

-5-
https://bit.ly/3MQ4KVi

Creamos los métodos para obtener la lista del servicio

El método onOninit() se ejecuta automáticamente al cargar el template


En el template list-school.component.html
<div class="container wrapper">
<div class="row">
<!-- table -->
<div class="col-md-12">
<div class="inner">
<h3>Escuelas Profesionales</h3>
<a class="btn btn-primary text-white add" routerLink="add-school">
<i class="fas fa-user-plus"></i> Agregar
</a>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Nombre</th>
<th scope="col">Fecha registro</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of schoolList">
<th scope="row">{{item.id}}</th>
<td>{{item.name}}</td>
<td>{{item.created_at}}</td>
<td>
<button type="button" class="btn btn-success btn-sm move-right"
[routerLink]="['/edit-issue/', item.id]">Edit</button>
<button type="button" class="btn btn-danger btn-sm"
(click)="deleteSchool(item.id)">Remove</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

-6-
https://bit.ly/3MQ4KVi

7. CREAR
En el servicio necesitamos una variable que contenga el objeto school

Declaramos el encabezado que pasara juntamente con el http post

Creamos el método

En add-school.component.ts
Inyectamos las dependencias

Creamos los métodos para enviar el formulario al servicio y limpiar el formulario

En add-school.component.ts
<div class="card mt-5">
<div class="card-body">
<h4 class="text-center">Registro de Escuela profesional</h4>
<form #schoolForm="ngForm" (ngSubmit)="submitForm(schoolForm)">
<input type="hidden" name="id" [(ngModel)]="schoolService.selectSchool.id">
<div class="form-group mb-3">
<input type="text" class="form-control" name="name"
[(ngModel)]="schoolService.selectSchool.name"
placeholder="Nombres">
</div>
<div class="form-group ">
<button class="btn btn-primary me-2" type="submit">
<i class="fas fa-plus-circle" ></i> Agregar
</button>
<button class="btn btn-secondary me-2" type="reset" (click)="resetForm(schoolForm)">
<i class="fas fa-sync-alt"></i> Resetear
</button>
<button class="btn btn-secondary" type="button" routerLink="/">

-7-
https://bit.ly/3MQ4KVi

<i class="fas fa-hand-point-left"></i> Cancelar


</button>
</div>
</form>
</div>
</div>

8. EDITAR
En el servicio

En list-school.component.ts

En list-school.component.html
En el botón editar

En Create-school.component.ts

9. ELIMINAR

10. SEGURIDAD CON JWT


https://jwt-auth.readthedocs.io/en/develop/
composer require tymon/jwt-auth:dev-develop --prefer-source

-8-
https://bit.ly/3MQ4KVi

Agregamos el provider en: config/app.php

Tymon\JWTAuth\Providers\LaravelServiceProvider::class,

Publicamos la configuración, puede ser en forma directa o seleccionando el provider


a publicar:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\
LaravelServiceProvider"

Generamos una clave secreta


php artisan jwt:secret

La clave secreta se agrega al final del archivo .env, que juntamente con el archivo en
config/jwt.php que se creó servirán para firmar los tokens.

Cambiar o agregar la forma de autenticación, en config/auth.php

-9-
https://bit.ly/3MQ4KVi

'api' => [
'driver' => 'jwt',
'provider' => 'users',
],

En app/Models/User.php

public function getJWTIdentifier(){


return $this->getKey();
}

public function getJWTCustomClaims(){


return [];
}

El primer método devuelve el identificador del JWT, el segundo define un arreglo


para almacenar Claims del JWT

11. GESTIÓN DE USUARIOS Y ACCESOS


Creamos un controlador:
php artisan make:controller AuthController
En routes/api.php, definimos las rutas

Route::group(['middleware' => 'api','prefix' => 'auth'], function ($router) {

-10-
https://bit.ly/3MQ4KVi

Route::post('login',[AuthController::class,'login']);
Route::post('logout',[AuthController::class,'logout']);
Route::post('refresh',[AuthController::class,'refresh']);
Route::post('register',[AuthController::class,'register']);
Route::get('me',[AuthController::class,'me']);
});

Codificamos los métodos en el controlador


https://jwt-auth.readthedocs.io/en/develop/quick-start/

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\User;

class AuthController extends Controller{

public function __construct(){


$this->middleware('auth:api', ['except' => ['login','register']]);
}

public function login(){


$credentials = request(['email', 'password']);

if (! $token = auth()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}

return $this->respondWithToken($token);
}

public function me(){


return response()->json(auth()->user());
}

public function logout(){


auth()->logout();

return response()->json(['message' => 'Successfully logged out']);


}

public function refresh(){


return $this->respondWithToken(auth()->refresh());
}

protected function respondWithToken($token){


return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
}

public function register(Request $request){


$validator=Validator::make($request->all(),[
'name'=>'required',
'email'=>'required|string|email|max:100|unique:users',
'password'=>'required|string|min:6'
]);

-11-
https://bit.ly/3MQ4KVi

if($validator->fails()){
return response()->json($validator->errors()->toJson(),400);
}
$user=User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
]);
return response()->json([
'message'=>'User successfully registered',
'user'=>$user
],201);
}
}

Probamos con postman


a. Crear usuario

b. Loguearse

-12-
https://bit.ly/3MQ4KVi

Si el usuario existe en la base de datos nos devuelve el token, tipo de token y tipo de
expiración
c. Accedemos a la ruta de perfil de usuario que está protegida

Pasamos en Authorization el tipo de token bear y copiamos el token generado al loguearse


y nos devuelve los datos del usuario.

12. LOGIN EN ANGULAR CON JWT


En el backend:
En SchoolController.php, agregar el constructor para bloquear el acceso
public function __construct(){
$this->middleware('auth:api');
}
Podemos agregar: $this->middleware('auth:api', ['except' => ['login','register']]);

-13-
https://bit.ly/3MQ4KVi

Agregamos a las rutas públicas dentro del middleware

EN EL FRONTEND
Creamos los componentes:
ng g component login/login
ng g component components/dashboard
Creamos un servicio:
ng g service services/auth

En auth.service.ts

API="http://127.0.0.1:8000/api/auth";

loginEmail(email:string, pass:string){
return this.http.post(this.API+"/login",{ email:email,password:pass });
}

logout() :void {
localStorage.setItem('isLoggedIn','false');
localStorage.removeItem('token');
}

En login.component.ts
public email:string="";
public password:string="";

onSubmitLogin(){
this.authService.loginEmail(this.email,this.password).subscribe((token:any)=>{
console.log(token.access_token);
localStorage.setItem('isLoggedIn',"true");
localStorage.setItem('token', token.access_token);
//this.toastr.success('Bienvenido: '+this.email);
this.router.navigate(['/dashboard']);
},err=>{
console.log("error: "+err);
}
);
}

En login.component.html
<main class="form-signin text-center mt-5">

<form (submit)="onSubmitLogin()">
<img class="mb-4" src="assets/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>

<div class="form-floating">
<input type="email" class="form-control" name="email" [(ngModel)]="email"

-14-
https://bit.ly/3MQ4KVi

placeholder="[email protected]">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" name="password" [(ngModel)]="password"
placeholder="Password">
<label for="floatingPassword">Password</label>
</div>

<div class="checkbox mb-3">


<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">&copy; 2017–2021</p>
</form>
</main>

En app-routing.module.ts

En app.component.html, agregamos el botón de logout


<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link btn btn-secondary ms-4" (click)="logout()"><i class="fas fa-sign-out-alt"></i>
Logout</a>
</li>
</ul>

En app.component.ts
logout() {
this.authservice.logout();
this.router.navigate(['/']);
}

Protegemos el listado de escuelas con el JWT


En school.service.ts, pasamos el JWT que se genera y captura en el login
reqHeader=new HttpHeaders({
'Content-Type':'aplication/json',
'Authorization':'bearer'+localStorage.getItem('token')
});

constructor(private http:HttpClient) { }
baseurl='http://127.0.0.1:8000/api/auth/';

//metodo GET
GetSchools():Observable<School>{
return this.http.get<School>(this.baseurl+'schools/',{headers:this.reqHeader});
}

13. GUARDS

-15-
https://bit.ly/3MQ4KVi

Creamos un guard: ng g guard guards/auth


En AuthService.ts, Agregamos el siguiente metodo
isLoggedIn(){
let status = false; //No se actuliza el inLogin a true
if (localStorage.getItem('isLoggedIn') == "true") {
status = true;
}else {
status = false;
}
return status;
}

En guards/auth.guard.ts

constructor(private router:Router, private authservice:AuthService) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

if (this.authservice.isLoggedIn()) {
return true;
}
// navigate to login page as user is not authenticated
this.router.navigate(['/']);
return false;
}

14.

-16-

También podría gustarte