Looking to hire Laravel developers? Try LaraJobs

laravel-goal-captcha maintained by irabbi360

Description
A football goal slider CAPTCHA system for Laravel — anti-bot, mobile-friendly, themeable.
Author
Last update
2026/05/28 21:45 (dev-main)
License
Downloads
15

Comments
comments powered by Disqus

⚽ GoalCaptcha — Laravel Football Goal Slider CAPTCHA

Tests Latest Version License

A production-ready, anti-bot football-goal slider CAPTCHA for Laravel — built like Sanctum / Telescope / Pulse.

Users drag a football into the goal net. The backend verifies alignment, drag speed, and human motion patterns. Bots are rejected.


Features

  • Football goal canvas scene — randomised stadium, goalkeeper, weather, decoys
  • 🖱 Drag slider interaction — mouse + touch, fully accessible (keyboard)
  • 🤖 Anti-bot motion analysis — speed variance, jerk, micro-corrections, interval consistency
  • 🔒 Replay attack protection — token deleted after first use
  • Auto-expiring challenges — configurable TTL (default 2 min)
  • 🎨 Theme system — football theme included, extendable
  • 📱 Mobile responsive — works on touch devices
  • 🧩 Blade component ``
  • 🖼 Vue 3 component `<GoalCaptcha />`
  • 🔌 Inertia / SPA / Nuxt compatible
  • 🗃 Pluggable storage — Redis, Cache (array/file/database)
  • 🎉 Event system — `CaptchaGenerated`, `CaptchaVerified`, `CaptchaFailed`

Installation

composer require irabbi360/laravel-goal-captcha

Publish assets and config:

php artisan goal-captcha:install

Quick Start — Blade

Add the component anywhere in your form:

<form method="POST" action="/login">
    @csrf
    <x-goal-captcha />
    <button type="submit">Login</button>
</form>

Protect the route with the middleware:

Route::middleware('goal-captcha')->post('/login', LoginController::class);

Quick Start — Vue 3 / Inertia

import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import vue from '@vitejs/plugin-vue'
import goalCaptcha from './vendor/irabbi360/laravel-goal-captcha/vite-plugin.js'

export default defineConfig({
    plugins: [
        laravel({ input: ['resources/js/app.js'] }),
        vue(),
        goalCaptcha(),   // ← adds the alias automatically
    ],
})
<script setup>
import { GoalCaptcha } from '@irabbi360/goal-captcha'
import '@irabbi360/goal-captcha/style'
const token = ref(null)
</script>

<template>
  <GoalCaptcha
    generate-url="/_goal_captcha/generate"
    verify-url="/_goal_captcha/verify"
    field-name="captcha_token"
    @verified="token = $event"
  />
</template>

Vue Plugin

import GoalCaptchaPlugin from '@irabbi360/goal-captcha'

createApp(App)
  .use(GoalCaptchaPlugin, {
    generateUrl: '/_goal_captcha/generate',
    verifyUrl:   '/_goal_captcha/verify',
    theme:       'football',
    difficulty:  'medium',
  })
  .mount('#app')

API Endpoints

Method URL Description
POST /_goal_captcha/generate Returns a CAPTCHA challenge
POST /_goal_captcha/verify Verifies submission, returns one-time token

Configuration

return [
    'driver'                   => 'cache',    // 'redis' | 'cache'
    'expire'                   => 120,
    'tolerance'                => 12,
    'min_drag_time'            => 400,
    'max_attempts'             => 5,
    'theme'                    => 'football',
    'difficulty'               => 'medium',   // 'easy' | 'medium' | 'hard'
    'enable_behavior_analysis' => true,
];

Events

Event::listen(CaptchaVerified::class, fn($e) => logger('solved', ['id' => $e->captcha->captchaId]));
Event When
CaptchaGenerated Challenge created
CaptchaVerified Human confirmed
CaptchaFailed Verification rejected

Architecture

src/
├── GoalCaptchaServiceProvider.php
├── LaravelGoalCaptcha.php
├── Contracts/          CaptchaStoreInterface, MotionAnalyzerInterface
├── DTO/                CaptchaData, VerificationData
├── Events/             Generated, Verified, Failed
├── Exceptions/         Expired, VerificationFailed, TooManyAttempts
├── Facades/            GoalCaptcha
├── Http/               Controllers, Middleware, Requests
├── Services/           Generator, Verifier, MotionAnalyzer, SceneBuilder, TokenManager
└── Support/Stores/     CacheStore, RedisStore

resources/js/
├── components/         GoalCaptcha.vue, GoalCanvas.vue, GoalSlider.vue, SuccessAnimation.vue
├── composables/        useGoalCaptcha.js
├── canvas/             renderer.js, animation.js, physics.js
├── utils/              motionTracker.js
└── index.js            Vue plugin + Blade auto-mount

Testing

composer test   # Pest (PHP)
npm run test    # Vitest (JS)

License

MIT — Fazle Rabbi