DEV Community

Pius oruko
Pius oruko

Posted on

Laravel Face Recognition and Authentication

Introduction
A recurring security and usability issue with web applications is passwords. They are frequently forgotten, reused, or compromised by phishing and credential stuffing attempts. By completely eliminating passwords, facial authentication provides a useful substitute that enhances user experience and security. In order to allow passwordless authentication, you will learn how to incorporate FACEIO facial recognition into a Laravel application. Using Laravel's authentication system and FACEIO's JavaScript SDK, the guide focuses on actual implementation and that includes backend validation, login processes, face enrollment, and security best practices.

What is FACEIO?
FACEIO is a cloud-based facial recognition and authentication platform built specifically for web applications. It allows developers to add secure biometric login using a lightweight JavaScript SDK, without building or maintaining computer vision or machine-learning infrastructure. FACEIO handles facial capture, recognition, and liveness detection in the browser and cloud, then returns a unique facial identifier that can be safely associated with a user account. No biometric images or videos are stored on your servers. FACEIO works across modern browsers and devices and follows GDPR-aligned privacy principles.

faceio hero section

How FACEIO Works with Laravel
FACEIO integrates with Laravel by using its client-side JavaScript SDK (fio.js) to handle all facial recognition interactions in the user's browser, while Laravel handles backend verification and session management. On the frontend, you call either enroll() to register a new user or authenticate() to recognize a returning user; both methods trigger the FACEIO widget and webcam access. Upon success, FACEIO returns a unique Facial ID for that user, which your Laravel app stores or verifies to log in the user. You never store actual biometric images in your database only this unique identifier tied to each use

Project Requirements
Before starting, ensure you have:

  • PHP 8.1 or later
  • Laravel 10+
  • A FACEIO account and public application ID
  • A webcam-enabled device for testing

Step 1: Create a New Laravel Project

composer create-project laravel/laravel faceio-auth
cd faceio-auth
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Configure your database credentials in the .env file.

Step 2: Update the Users Table
FACEIO returns a unique facial identifier for each enrolled user. This value must be stored in your database.

Create a migration:

php artisan make:migration add_faceio_id_to_users_table
Enter fullscreen mode Exit fullscreen mode

Update the migration file:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->string('faceio_id')->nullable()->unique();
});
Enter fullscreen mode Exit fullscreen mode

Run migrations:

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Step 3: Register a FACEIO Application
Go to the FACEIO Console and create a new application and copy your Public ID. This ID is used on the frontend to initialize the FACEIO SDK.

Step 4: Include FACEIO SDK in Laravel Blade
Add the FACEIO script to your main Blade layout file:

<script src="https://cdn.faceio.net/fio.js"></script>
<script>
  const faceio = new faceIO("YOUR_FACEIO_PUBLIC_ID");
</script>
Enter fullscreen mode Exit fullscreen mode

This initializes FACEIO and makes facial authentication available throughout your app.

Step 5: Facial Enrollment (User Registration)
Facial enrollment links a user account to a biometric identity.


**
Enrollment Button**

<button onclick="enrollUser()">Register with Face</button>
Enter fullscreen mode Exit fullscreen mode

Enrollment Script

<script>
async function enrollUser() {
  try {
    const userInfo = await faceio.enroll({
      locale: "auto",
      payload: {
        email: "{{ auth()->user()->email }}"
      }
    });

    await fetch('/faceio/register', {
      method: 'POST',
      headers: {
        'X-CSRF-TOKEN': '{{ csrf_token() }}',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        faceio_id: userInfo.facialId
      })
    });

    alert("Face registered successfully");
  } catch (error) {
    console.error(error);
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

This script handles facial enrollment on the frontend using FACEIO. When called, it opens the FACEIO enrollment widget and uses the user's webcam to capture their face. Upon successful enrollment, FACEIO returns a unique facial identifier (facialId). The script then sends this identifier to the Laravel backend via a secure POST request, including a CSRF token for protection. Laravel stores the identifier in the database linked to the authenticated user. Finally, the script shows a confirmation alert to the user. If any error occurs during enrollment or submission, it is logged to the browser console.

Step 6: Laravel Controller for Face Enrollment

Create a controller:

php artisan make:controller FaceAuthController
Enter fullscreen mode Exit fullscreen mode

Add the enrollment logic:

use Illuminate\Http\Request;

class FaceIOController extends Controller
{
    public function registerFace(Request $request)
    {
        $request->validate([
            'faceio_id' => 'required|string|unique:users,faceio_id'
        ]);

        $user = auth()->user();
        $user->faceio_id = $request->faceio_id;
        $user->save();

        return response()->json(['success' => true]);
    }
}
Enter fullscreen mode Exit fullscreen mode

This controller method handles facial enrollment by linking a FACEIO facial identity to an existing Laravel user account. When the frontend completes face enrollment, it sends the generated facial ID to this endpoint. Laravel first validates the request to ensure the facial ID exists, is correctly formatted, and is not already associated with another user. The method then retrieves the currently authenticated user and stores the facial ID in the database. No biometric images or facial data are saved, Only the unique identifier provided by FACEIO. Finally, the controller returns a JSON response to confirm that the enrollment process completed successfully and securely.

Step 7: Facial Login (Authentication)
Facial authentication verifies the user and logs them in without a password.

Login Button

<button onclick="loginWithFace()">Login with Face</button>
Enter fullscreen mode Exit fullscreen mode

Login Script

<script>
async function loginWithFace() {
  try {
    const authResponse = await faceio.authenticate({
      locale: "auto"
    });

    await fetch('/faceio/login', {
      method: 'POST',
      headers: {
        'X-CSRF-TOKEN': '{{ csrf_token() }}',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        faceio_id: authResponse.facialId
      })
    });

    window.location.href = "/dashboard";
  } catch (error) {
    console.error(error);
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

This script handles facial login on the frontend using FACEIO. When triggered, it opens the FACEIO authentication widget and accesses the user's webcam to verify their face. If authentication succeeds, FACEIO returns a unique facial identifier. The script then sends this identifier securely to the Laravel backend using a POST request, including a CSRF token for protection. Once Laravel confirms the user and creates a session, the browser redirects the user to the dashboard. If any step fails, the error is logged to the console.

Step 8: Laravel Facial Login Controller
Add login logic to the controller:

use App\Models\User;
use Illuminate\Support\Facades\Auth;

public function login(Request $request)
{
    $user = User::where('faceio_id', $request->faceio_id)->firstOrFail();
    Auth::login($user);

    return response()->json(['success' => true]);
}
Enter fullscreen mode Exit fullscreen mode

This method handles facial login after FACEIO successfully authenticates a user on the frontend. When FACEIO returns a facial ID, Laravel receives it through the request. The method searches the users table for a record with a matching FACEIO facial ID. If no matching user is found, the request automatically fails, preventing unauthorized access. Once a matching user is located, Laravel logs the user in using its built-in authentication system, creating a valid session just like a traditional password-based login. The method then returns a JSON response to confirm that authentication was successful and the user is now logged in.

Step 9: Routes Configuration
Add routes to web.php:

use App\Http\Controllers\FaceIOController;

Route::post('/faceio/register', [FaceIOController::class, 'registerFace']);
Route::post('/faceio/login', [FaceIOController::class, 'login']);
Enter fullscreen mode Exit fullscreen mode

This code defines two POST routes in Laravel that handle FACEIO-related authentication actions. The first route listens for requests sent after a user successfully enrolls their face and maps them to the registerFace method in the FaceIOController, where the facial ID is stored in the database. The second route listens for facial login requests and maps them to the login method, which authenticates the user using the FACEIO facial ID. Both routes use POST because they handle sensitive data and modify authentication state. These routes act as the secure bridge between the FACEIO frontend SDK and Laravel's backend authentication system.
Environment Configuration
Update your .env file:

# Laravel Environment
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:YOUR_APP_KEY_HERE
APP_DEBUG=true
APP_URL=http://localhost:8000

# Database Configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=face_auth
DB_USERNAME=root
DB_PASSWORD=

# FACEIO Configuration
FACEIO_APP_ID=your_actual_app_id_here
Enter fullscreen mode Exit fullscreen mode

Notes:

  • Replace your_actual_app_id_here with the public App ID from your FACEIO console.
  • Ensure APP_KEY is generated via php artisan key:generate.
  • The database credentials should match your local MySQL setup. Running the Application Start the development server:
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

  • Mandatory Security Settings in FACEIO
  • Enable Liveness Detection: Prevents photo/video spoofing attacks
  • Use HTTPS: Required for browser camera access
  • Restrict Widget Instantiation: Limit to authorized domains only
  • Enable Webhooks: Server-side validation of all events
  • Reject Empty Origin Headers: Prevent forged requests
  • Prevent Duplicate Enrollments: Block same user enrolling multiple times

Recommended Additional Settings:

  • Require PIN Confirmation: Always ask for PIN during authentication
  • Reject Weak PINs: Block patterns like "0000" or "1234"
  • Enforce PIN Uniqueness: Ensure unique PINs across users
  • Forbid Minors: Age verification for sensitive services
  • Ignore Obscured Faces: Discard masked/poorly lit faces
  • Country Restrictions: Limit access by geographic location

Conclusion

Integrating FACEIO with Laravel provides a modern, secure, and user-friendly alternative to traditional password-based authentication. By leveraging FACEIO's cloud-based facial recognition and liveness detection, Laravel applications can implement passwordless login, ensuring a seamless user experience while maintaining high security standards. The integration keeps sensitive biometric data off your servers, storing only unique facial identifiers tied to user accounts. This approach reduces risks associated with password reuse, phishing, and credential theft. Whether for employee login systems, event check-ins, or secure dashboards, combining Laravel's robust backend with FACEIO's biometric capabilities enables developers to build scalable, secure, and cutting-edge authentication solutions.

Top comments (0)