Introduction
Integrate Botbye bot protection into your Laravel application using middleware. This guide shows how to protect your Laravel routes with minimal configuration.
Installation
Install the SDK via Composer:
1
composer require botbye/botbye-php-sdk
Configuration
Register the Botbye client in your AppServiceProvider:
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
<?php
namespace App\Providers;
use Botbye\Client\BotbyeClient;
use Botbye\Client\BotbyeConfig;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(BotbyeClient::class, function ($app) {
$config = new BotbyeConfig(
// Use your project server-key
serverKey: '00000000-0000-0000-0000-000000000000'
);
return new BotbyeClient($config);
});
}
public function boot(): void
{
//
}
}
Usage
1. Create a middleware to validate requests:
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
<?php
namespace App\Http\Middleware;
use Botbye\Client\BotbyeClient;
use Botbye\Model\ConnectionDetails;
use Botbye\Model\Headers;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class BotbyeMiddleware
{
public function __construct(
private BotbyeClient $botbye
) {
}
public function handle(Request $request, Closure $next): Response
{
$connectionDetails = new ConnectionDetails(
remoteAddr: $request->ip(),
requestMethod: $request->method(),
requestUri: $request->getRequestUri(),
serverPort: $request->getPort(),
serverName: $request->getHost()
);
$headers = Headers::fromArray($request->headers->all());
// Get token from header or any place you store it.
// For example in "x-botbye-token" header
$token = $request->header('x-botbye-token')
$response = $this->botbye->validateRequest(
token: $token,
connectionDetails: $connectionDetails,
headers: $headers,
customFields: [
'user_id' => $request->user()?->id,
'session_id' => $request->session()->getId(),
]
);
if ($response->result !== null && !$response->result->isAllowed) {
abort(403, 'Access denied by Botbye protection');
}
return $next($request);
}
}
2. Add the middleware to app/Http/Kernel.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middlewareAliases = [
// ... other middleware
'botbye' => \App\Http\Middleware\BotbyeMiddleware::class,
];
}
3. Apply the middleware to specific routes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
use Illuminate\Support\Facades\Route;
// Protect a single route
Route::post('/api/checkout', [CheckoutController::class, 'process'])
->middleware('botbye');
// Protect a group of routes
Route::middleware(['botbye'])->group(function () {
Route::post('/api/login', [AuthController::class, 'login']);
Route::post('/api/register', [AuthController::class, 'register']);
Route::post('/api/checkout', [CheckoutController::class, 'process']);
});
// Protect all API routes
Route::middleware(['api', 'botbye'])->prefix('api')->group(function () {
// Your API routes
});
Advanced Configuration
Custom HTTP Client
Configure a custom HTTP client with Laravel's HTTP client:
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
<?php
namespace App\Providers;
use Botbye\Client\BotbyeClient;
use Botbye\Client\BotbyeConfig;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\HttpClient\HttpClient;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(BotbyeClient::class, function ($app) {
$config = new BotbyeConfig(
serverKey: '00000000-0000-0000-0000-000000000000',
);
$httpClient = HttpClient::create([
'timeout' => 1,
'max_redirects' => 0,
]);
return new BotbyeClient($config, $httpClient);
});
}
}
Logging Integration
Integrate with Laravel's logging system:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
namespace App\Providers;
use Botbye\Client\BotbyeClient;
use Botbye\Client\BotbyeConfig;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(BotbyeClient::class, function ($app) {
$config = new BotbyeConfig(
serverKey: '00000000-0000-0000-0000-000000000000'
);
// Use Laravel's PSR-3 compatible logger
return new BotbyeClient($config, null, Log::channel('botbye'));
});
}
}
Configure the log channel in config/logging.php:
1
2
3
4
5
6
7
8
9
10
'channels' => [
// ... other channels
'botbye' => [
'driver' => 'daily',
'path' => storage_path('logs/botbye.log'),
'level' => 'warning',
'days' => 14,
],
],
Best Practices
1. Selective Protection - Only apply middleware to routes that need protection
2. Custom Fields - You cab pass user context for better analysis
3. Logging - Monitor Botbye errors and blocked requests
Testing
Mock the Botbye client in your tests:
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
<?php
namespace Tests\Feature;
use Botbye\Client\BotbyeClient;
use Botbye\Model\BotbyeResponse;
use Botbye\Model\BotbyeResult;
use Tests\TestCase;
class ProtectedRouteTest extends TestCase
{
public function test_allowed_request()
{
$mockClient = $this->mock(BotbyeClient::class);
$mockClient->shouldReceive('validateRequest')
->once()
->andReturn(new BotbyeResponse(
result: new BotbyeResult(isAllowed: true),
error: null
));
$response = $this->post('/api/checkout', [
'item' => 'test',
]);
$response->assertStatus(200);
}
public function test_blocked_request()
{
$mockClient = $this->mock(BotbyeClient::class);
$mockClient->shouldReceive('validateRequest')
->once()
->andReturn(new BotbyeResponse(
result: new BotbyeResult(isAllowed: false),
error: null
));
$response = $this->post('/api/checkout', [
'item' => 'test',
]);
$response->assertStatus(403);
}
}
Examples of BotBye API responses
Bot detected:
1
2
3
4
5
6
7
{
"reqId": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"result": {
"isAllowed": false
},
"error": "Automation tool used"
}
Bot not detected:
1
2
3
4
5
6
7
{
"reqId": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"result": {
"isAllowed": true
},
"error": null
}
Request banned by custom rule:
1
2
3
4
5
6
7
8
9
{
"reqId": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"result": {
"isAllowed": false
},
"error": {
"message": "Banned by rule: MY_CUSTOM_RULE"
}
}
Invalid server-key:
1
2
3
4
5
6
7
{
"reqId": "f77b2abd-c5d7-44f0-be4f-174b04876583",
"result": null,
"error": {
"message": "[BotBye] Bad Request: Invalid Server Key"
}
}