This document shows how to integrate PPS-PHP with Laravel.
composer require pps-protocol/pps-php
use App\Http\Controllers\PpsAuthController;
Route::get('/pps/challenge', [PpsAuthController::class, 'challenge']);
Route::post('/pps/verify', [PpsAuthController::class, 'verify']);
Route::post('/pps/register', [PpsAuthController::class, 'register']);
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Pps\Server\AuthenticationHandler;
use Pps\Server\ChallengeGenerator;
use Pps\Server\RegistrationHandler;
use Pps\Storage\PdoStorage;
use Pps\Util\SystemTimeProvider;
class PpsAuthController extends Controller
{
private function storage(): PdoStorage
{
$pdo = new \PDO(
config('database.connections.mysql.dsn'),
config('database.connections.mysql.username'),
config('database.connections.mysql.password')
);
return new PdoStorage($pdo);
}
public function challenge(): JsonResponse
{
$generator = new ChallengeGenerator(new SystemTimeProvider());
$challenge = $generator->create(config('app.url'));
session(['pps_nonce' => $challenge->nonceB64u]);
return response()->json([
'nonce' => $challenge->nonceB64u,
'epoch' => $challenge->epoch,
'qr_payload' => $challenge->qrPayload,
]);
}
public function verify(Request $request): JsonResponse
{
$request->validate([
'pulse_token' => 'required|string',
'trust_code' => 'nullable|string',
]);
$handler = new AuthenticationHandler($this->storage(), new SystemTimeProvider());
$result = $handler->verify(
pulseToken: $request->input('pulse_token'),
rpId: config('app.url'),
nonceB64u: session('pps_nonce'),
trustCode: $request->input('trust_code')
);
if ($result->honey) {
return response()->json(['status' => 'ok']);
}
if (!$result->ok) {
return response()->json(['status' => 'error'], 401);
}
session()->forget('pps_nonce');
return response()->json(['status' => 'ok']);
}
public function register(Request $request): JsonResponse
{
$request->validate([
'registration_token' => 'required|string',
'nonce' => 'required|string',
]);
$handler = new RegistrationHandler($this->storage(), new SystemTimeProvider());
$result = $handler->verify(
token: $request->input('registration_token'),
rpId: config('app.url'),
nonceB64u: $request->input('nonce')
);
if (!$result->ok) {
return response()->json(['status' => 'error'], 400);
}
return response()->json(['status' => 'ok']);
}
}
You may bind storage in a service provider:
use Pps\Storage\PdoStorage;
use Pps\Storage\StorageInterface;
$this->app->singleton(StorageInterface::class, function ($app) {
return new PdoStorage($app['db']->connection()->getPdo());
});