In this tutorial you will learn about the Laravel 8 Angular Token Based Authentication with JWT and its application with practical example.
In this Laravel 8 Angular Token Based Authentication with JWT Tutorial I’ll show you how to create REST API with secure jwt token based authentication in Laravel 8 Angular application using JWT (JSON Web Token) . In this tutorial you will learn to create laravel rest api with token based authentication in laravel angular application. In this article, we will learn to create fully functional restful API with JWT Authentication in Laravel 8 angular application. We will also learn to create login and registration api using jwt authentication in laravel 8. In this example I will guide you through how to create fully functional restful API with JWT Authentication in Laravel 8 for laravel and angular application.
- Laravel 8 Angular Token Based Authentication with JWT
- Laravel and Angular Project Structure
- Create Laravel JWT Authentication REST API
- Install and Configure Angular
- Adding up HttpClient
- Insert Reactive Form Service
- Create CORS Middleware
- Consume Laravel REST API with Angular Service
- Create Authentication State to Multiple Components
- Set Token in Header with HttpInterceptor
- Angular User Registration Component
- Angular User Login Component
- Angular User Profile Component
- Angular User Logout Component
- Start The Laravel App
- Start The Angular App
In laravel token based authentication provides secure user authentication system. Token based authentication restrain unauthenticated user from accessing the application. In this example we will be using JWT (JSON Web Token) token based authentication integrated with laravel application. In this example I’ll also show you how to install jwt auth and configure jwt auth in laravel 8.
Laravel 8 Angular Token Based Authentication with JWT
- Clone Laravel JWT Auth Repo
- Install and Configure Angular
- Create CORS Middleware
- Consume Angular Service
- Set JWT Token with Http Interceptor
- Angular User Registration Component
- Angular User Login Component
- Angular User Profile Component
- Angular User Lgout Component
Laravel and Angular Project Structure
Create new project directory using following command:
1 |
mkdir your_project_name |
and this folder will have backend (Laravel API) and frontend (Angular) folders inside it.
1 2 3 |
- your_project_name --- backend --- frontend |
Create Laravel JWT Authentication REST API
In this step we will clone the Laravel JWT Auth REST API project, switch to backend folder inside your project folder using following command:
1 |
cd backend |
Now we will download the project from GitHub repo link, then unzip all the files inside the backend folder:
Now, run the following commands to install required dependencies for node and composer for your laravel auth project:
1 2 3 4 5 |
$ composer install $ cp .env.example .env $ php artisan key:generate $ php artisan migrate $ php artisan serve |
Start the project using following command:
1 |
php artisan serve |
Now project will be started at
1 |
http://127.0.0.1:8000 |
Use above link as base URL for accessing following api
Method | Endpoint |
---|---|
POST | /api/auth/register |
POST | /api/auth/login |
GET | /api/auth/user-profile |
POST | /api/auth/refresh |
POST | /api/auth/logout |
Install and Configure Angular
In this step you need to switch into the frontend folder and install Angular application using following command:
1 |
ng new frontend && cd frontend |
Next, we will create following angular components for user authentication system.
1 2 3 4 5 |
ng g c components/signin ng g c components/signup ng g c components/user-profile |
Now we will be installing bootstrap framework to design authentication forms.
1 |
npm install bootstrap |
Open angular.json file and define the bootstrap CSS path as following:
1 2 3 4 |
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.scss" ] |
We are ready to start angular app, run the following command to start angular application:
1 |
ng serve --open |
Adding up HttpClient
Lets import Http client module inside the app.module.ts file. The Http client module will handle the HTTP requests,
1 2 3 4 5 6 7 |
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule ] }) |
Insert Reactive Form Service
As we will be using ReactiveFormsModule and FormsModule. Lets Import and inject both the APIs in app.module.ts file.
1 2 3 4 5 6 7 8 |
import { ReactiveFormsModule, FormsModule } from '@angular/forms'; @NgModule({ imports: [ ReactiveFormsModule, FormsModule ], }) |
Create CORS Middleware
In this step we will create a CORS middleware, this will enable us to share resources between two different domain/ports. Our backend is running on PORT:8000 and frontend running on PORT:4200. Switch to “backend” folder and run the following command:
1 |
php artisan make:middleware CORS |
Open app/Http/Middleware/CORS.php file and set the Acess-Control-Allow-Origin headers as following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Http\Middleware; use Illuminate\Http\Request; use Closure; class CORS { public function handle(Request $request, Closure $next) { header('Acess-Control-Allow-Origin: *'); header('Acess-Control-Allow-Origin: Content-type, X-Auth-Token, Authorization, Origin'); return $next($request); } } |
Open app/Http/Kernel.php file and add the define the “guest” CORS middleware inside the $routeMiddleware array.
1 2 3 4 |
protected $routeMiddleware = [ ... 'guest' => \App\Http\Middleware\CORS::class, ]; |
Now, restart the backend application using following commnad:
1 |
php artisan serve |
Consume Laravel REST API with Angular Service
In this step we will generate a Angular service file using following command:
1 |
ng g s shared/auth |
Now, open shared/auth.service.ts file and put the following code in it.
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 |
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; // User interface export class User { name: String; email: String; password: String; password_confirmation: String } @Injectable({ providedIn: 'root' }) export class AuthService { constructor(private http: HttpClient) { } // User registration register(user: User): Observable<any> { return this.http.post('http://127.0.0.1:8000/api/auth/register', user); } // Login signin(user: User): Observable<any> { return this.http.post<any>('http://127.0.0.1:8000/api/auth/login', user); } // Access user profile profileUser(): Observable<any> { return this.http.get('http://127.0.0.1:8000/api/auth/user-profile'); } } |
Now we will be create a angular service to validate & configure laravel JWT Token in Angular application. Run the following command to generate service file:
1 |
ng g s shared/token |
Lets open shared/token.service.ts file and put the following code in it.
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 43 44 45 46 47 48 49 50 51 52 53 |
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class TokenService { private issuer = { login: 'http://127.0.0.1:8000/api/auth/login', register: 'http://127.0.0.1:8000/api/auth/register' } constructor() { } handleData(token){ localStorage.setItem('auth_token', token); } getToken(){ return localStorage.getItem('auth_token'); } // Verify the token isValidToken(){ const token = this.getToken(); if(token){ const payload = this.payload(token); if(payload){ return Object.values(this.issuer).indexOf(payload.iss) > -1 ? true : false; } } else { return false; } } payload(token) { const jwtPayload = token.split('.')[1]; return JSON.parse(atob(jwtPayload)); } // User state based on valid token isLoggedIn() { return this.isValidToken(); } // Remove token removeToken(){ localStorage.removeItem('auth_token'); } } |
Create Authentication State to Multiple Components
Now we will create auth state that can be accessed in components. Use the following command to create auth state:
1 |
ng g s shared/auth-state |
Open shared/auth-state.service.ts file and put the following code in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { TokenService } from '../shared/token.service'; @Injectable({ providedIn: 'root' }) export class AuthStateService { private userState = new BehaviorSubject<boolean>(this.token.isLoggedIn()); userAuthState = this.userState.asObservable(); constructor( public token: TokenService ) { } setAuthState(value: boolean) { this.userState.next(value); } } |
Set Token in Header with HttpInterceptor
In this step we will set auth token in Header using HttpInterceptor class. Lets create shared/auth.interceptor.ts inside the frontend folder and place the following code in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { Injectable } from "@angular/core"; import { HttpInterceptor, HttpRequest, HttpHandler } from "@angular/common/http"; import { TokenService } from "../shared/token.service"; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private tokenService: TokenService) { } intercept(req: HttpRequest<any>, next: HttpHandler) { const accessToken = this.tokenService.getToken(); req = req.clone({ setHeaders: { Authorization: "Bearer " + accessToken } }); return next.handle(req); } } |
Put the following code in the app.module.ts file.
1 2 3 4 5 6 7 8 9 10 11 12 |
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from './shared/auth.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }) |
Angular User Registration Component
In this step we will setup angular register component, this will register a user using Laravel signup REST API in angular application. Lets open signup.component.ts file and put the following code in it.
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 43 44 45 46 |
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { AuthService } from './../../shared/auth.service'; import { FormBuilder, FormGroup } from "@angular/forms"; @Component({ selector: 'app-signup', templateUrl: './signup.component.html', styleUrls: ['./signup.component.scss'] }) export class SignupComponent implements OnInit { registerForm: FormGroup; errors = null; constructor( public router: Router, public fb: FormBuilder, public authService: AuthService ) { this.registerForm = this.fb.group({ name: [''], email: [''], password: [''], password_confirmation: [''] }) } ngOnInit() { } onSubmit() { this.authService.register(this.registerForm.value).subscribe( result => { console.log(result) }, error => { this.errors = error.error; }, () => { this.registerForm.reset() this.router.navigate(['login']); } ) } } |
Open signup.component.html file and insert the following code.
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 |
<div class="auth-wrapper"> <form class="form-signin" [formGroup]="registerForm" (ngSubmit)="onSubmit()"> <h3 class="h3 mb-3 font-weight-normal text-center">Register User</h3> <!-- Errors --> <div *ngIf="errors?.name" class="alert alert-danger mt-3"> {{ errors?.name }} </div> <div *ngIf="errors?.email" class="alert alert-danger mt-3"> {{ errors?.email }} </div> <div *ngIf="errors?.password" class="alert alert-danger mt-3"> {{ errors?.password }} </div> <div *ngIf="errors?.password_confirmation" class="alert alert-danger mt-3"> {{ errors?.password_confirmation }} </div> <!-- Signup form --> <div class="form-group"> <label>Name</label> <input type="text" class="form-control" formControlName="name"> </div> <div class="form-group"> <label>Email address</label> <input type="email" class="form-control" formControlName="email"> </div> <div class="form-group"> <label>Password</label> <input type="password" class="form-control" formControlName="password"> </div> <div class="form-group"> <label>Confirm Password</label> <input type="password" class="form-control" formControlName="password_confirmation"> </div> <button type="submit" class="btn btn-block btn-primary">Register User</button> </form> </div> |
Angular User Login Component
In this step we will setup angular user login component, this will login user securly consuming Laravel login REST API in angular application. Lets open signin.component.ts file and put the following code in it.
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 43 44 45 46 47 48 49 50 51 52 53 |
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { AuthService } from './../../shared/auth.service'; import { FormBuilder, FormGroup } from "@angular/forms"; import { TokenService } from '../../shared/token.service'; import { AuthStateService } from '../../shared/auth-state.service'; @Component({ selector: 'app-signin', templateUrl: './signin.component.html', styleUrls: ['./signin.component.scss'] }) export class SigninComponent implements OnInit { loginForm: FormGroup; errors = null; constructor( public router: Router, public fb: FormBuilder, public authService: AuthService, private token: TokenService, private authState: AuthStateService, ) { this.loginForm = this.fb.group({ email: [], password: [] }) } ngOnInit() { } onSubmit() { this.authService.signin(this.loginForm.value).subscribe( result => { this.responseHandler(result); }, error => { this.errors = error.error; },() => { this.authState.setAuthState(true); this.loginForm.reset() this.router.navigate(['profile']); } ); } // Handle response responseHandler(data){ this.token.handleData(data.access_token); } } |
Open signin.component.html file and include the given below code.
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 |
<div class="auth-wrapper"> <form class="form-signin" [formGroup]="loginForm" (ngSubmit)="onSubmit()"> <h3 class="h3 mb-3 font-weight-normal text-center">Sign in</h3> <!-- Errors --> <div *ngIf="errors?.email" class="alert alert-danger mt-3"> {{ errors?.email }} </div> <div *ngIf="errors?.password" class="alert alert-danger mt-3"> {{ errors?.password }} </div> <div *ngIf="errors?.error" class="alert alert-danger mt-3"> {{ errors?.error }} </div> <!-- Login --> <div class="form-group"> <label>Email address</label> <input type="email" class="form-control" formControlName="email"> </div> <div class="form-group"> <label>Password</label> <input type="password" class="form-control" formControlName="password"> </div> <button type="submit" class="btn btn-block btn-primary">Log in</button> </form> </div> |
Angular User Profile Component
In this step we will setup angular user profile component, this will display user profile consuming Laravel user profile REST API in angular application. Lets open user-profile.component.ts file and put the following code in it.
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 |
import { Component, OnInit } from '@angular/core'; import { AuthService } from './../../shared/auth.service'; // User interface export class User { name: String; email: String; } @Component({ selector: 'app-user-profile', templateUrl: './user-profile.component.html', styleUrls: ['./user-profile.component.scss'] }) export class UserProfileComponent implements OnInit { UserProfile: User; constructor( public authService: AuthService ) { this.authService.profileUser().subscribe((data:any) => { this.UserProfile = data; }) } ngOnInit() { } } |
Open user-profile.component.html file and incorporate the following code within.
1 2 3 4 5 6 7 8 9 10 11 |
<div class="container"> <div class="card inner-main"> <div class="card-header"> User Profile </div> <div class="card-body"> <p class="card-text">Name: <strong>{{UserProfile?.name}}</strong></p> <p class="card-text">Email: <strong>{{UserProfile?.email}}</strong></p> </div> </div> </div> |
Angular User Logout Component
In this step we will setup angular user logout functionality component, this will logout user consuming Laravel user logout REST API in angular application.
In this step you will create user logout functionality consuming Laravel user logout REST API in angular application. Lets open app.component.ts file and put the following code in it.
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 |
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { TokenService } from './shared/token.service'; import { AuthStateService } from './shared/auth-state.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { isSignedIn: boolean; constructor( private auth: AuthStateService, public router: Router, public token: TokenService, ) { } ngOnInit() { this.auth.userAuthState.subscribe(val => { this.isSignedIn = val; }); } // Signout signOut() { this.auth.setAuthState(false); this.token.removeToken(); this.router.navigate(['login']); } } |
Open app.component.html file and insert the following code.
1 2 3 4 5 6 7 8 9 10 11 |
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm fixed-top"> <h5 class="my-0 mr-md-auto font-weight-normal">Laravel Angular JWT Auth</h5> <nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" routerLink="/profile" *ngIf="isSignedIn">User Profile</a> <a class="p-2 text-dark" *ngIf="!isSignedIn" routerLink="/login">Log in</a> <a class="p-2 text-dark" routerLink="/register">Register</a> </nav> <button class="btn btn-outline-primary" (click)="signOut()" *ngIf="isSignedIn">Log out</button> </div> <router-outlet></router-outlet> |
Start The Laravel App
Now we are ready to run our example so lets start the laravel development server using following artisan command –
1 |
cd backend && php artisan serve |
Start The Angular App
Open another terminal,switch into frontend directory and start the angular development server using following command –
1 |
cd frontend && ng serve --open |