[[oktatas:web:angular|< Angular]] ====== Angular - Laravel API azonosítás ====== * **Szerző:** Sallai András * Copyright (c) Sallai András, 2021, 2022 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]] * Web: https://szit.hu ===== Laravel ===== Az alábbi leírásban feltételezzük, hogy a Laravel oldalon az API számára Sanctum azonosítás lett beállítva. Ebben az esetben, az azonosításhoz egy POST kérésre van szükségünk, az azonosító adatok a "body"-ban utaznak. ===== Angular szerviz ===== Ebben a leírásban fetch() függvény helyett az Angular saját kliensét, a **HttpClient**-t használjuk. Az auth szolgáltatást egy shared nevű könyvtárban hozzuk létre. Nem kötelező ilyen könyvtár létrehozása, de ezzel elválaszthatjuk az alkalmazás többi részétől. A projekt könyvtárában: mkdir src/app/shared ng generate service shared/auth Az **auth.service.ts** fájlban importáljuk a HttpClient modult: import { HttpClient } from '@angular/common/http'; Injektáljuk a HttpClient osztályt a konstruktor paramétereként: constructor(private http: HttpClient) { } Létrehozunk egy **authUser()** vagy egy **login()** metódust az azonosításhoz. authUser(name: string, password: string) { let url = 'http://localhost:8000/api/login'; let authData = { "name": name, "password": password } return this.http.post(url, authData); } ===== Login felület ===== A **login.component.html** sablonban és a **login.component.ts** fájlban csoportosított reaktív űrlapot használunk.


===== Login TypeScript ===== Importáljuk a **FormGroup**, **FormBuilder** és az általunk készített **AuthService** osztályokat. import { FormBuilder, FormGroup } from '@angular/forms'; import { AuthService } from '../auth.service'; Készítünk egy FormGroup példányt loginForm néven: loginForm !: FormGroup; Injektáljuk az AuthService, és FormBuilder osztályokat: constructor( private authService: AuthService, private formBuilder: FormBuilder ) { } A loginForm objektumot előkészítjük az ngOnInit() metódusban: this.loginForm = this.formBuilder.group({ name: [''], password: [''] }) Az onLogin() metódusban elkérjük az auth szervíztől az azonosítás adatait. onLogin() { let user = this.loginForm.value.name; let pass = this.loginForm.value.password; this.authService.authUser(user, pass).subscribe({ next: data => { localStorage.setItem('token', data.token); localStorage.setItem('username', data.name); }, error: err => { console.log('Hiba! Az azonosítás sikertelen'); } }); } ===== Logout ===== Készíthetünk egy api/logout nevű végpontot Laravellel. Elküldjük a felhasználói tokent POST metódussal. Az API oldalon, a token törlődik. ===== Guard ===== Az egyes útvonalak védelméről a guard nevű eszközzel tudunk gondoskodni. A shared nevű könyvtárban fogom létrehozni (nem kötelező itt létrehozni): ng g guard shared/auth Létrehozáskor rákérdez milyen típusokat szeretnénk: >(*) CanActivate ( ) CanActivateChild ( ) CanDeactivate ( ) CanLoad A szóközzel jelölhetek ki, a le és fel billentyűvel választhatok, az Enter billentyűre továbblép. isLoggedIn() { if (localStorage.getItem('currentUser') === null) { return false; } let data:any = localStorage.getItem('currentUser'); let currentUser = JSON.parse(data); let token = currentUser.token; return token; } import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate } from '@angular/router'; import { Router, RouterStateSnapshot, UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor( private auth: AuthService, private router: Router ) {} canActivate(){ if( this.auth.isLoggedIn() ) { return true; } this.router.navigate(['login']); return false; } } const routes: Routes = [ { path: 'students', component: StudentComponent, canActivate: [AuthGuard] }, {path: '**', component: NopageComponent} ]; ===== Függelék ===== import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { AuthService } from '../shared/auth.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { loginForm !: FormGroup constructor( private auth: AuthService, private formBuilder: FormBuilder, private router: Router ) { } ngOnInit(): void { this.loginForm = this.formBuilder.group({ user: [''], pass: [''] }); } login() { let user = this.loginForm.value.user; let pass = this.loginForm.value.pass; this.auth.login(user, pass).subscribe({ next: res => { if (res.success) { let data = JSON.stringify({ token: res.data.token, name: res.data.name }); localStorage.setItem('currentUser', data); this.router.navigate(['groups']); } }, error: err => { alert('Hiba! Az azonosítás sikertelen!') } }); } } Laravel AuthController login függvény: public function login( Request $request ) { if( Auth::attempt([ "name" => $request->name, "password" => $request->password ])) { $authUser = Auth::user(); $success[ "token" ] = $authUser->createToken( "myapptoken" )->plainTextToken; $success[ "name" ] = $authUser->name; return $this->sendResponse( $success, "User signed in" ); }else { return $this->sendError( "Sikertelen bejelentkezés", [ "error" => "Hibás adatok" ], 401); } } Cookie használata: document.cookie = (`currentUser = ${data}`)