[[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}`)