1. Go to this page and download the library: Download funnelchat20/platform-gate library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
funnelchat20 / platform-gate example snippets
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('platform-gate:purge-usage')->daily()->onOneServer()->withoutOverlapping();
// bootstrap/app.php
use Illuminate\Http\Request;
->withMiddleware(function (Middleware $middleware) {
// Sin X-Forwarded-Host ni X-Forwarded-Prefix: el host público lo fija el portero, y
// sólo cuando el pedido trae el secreto del borde. Ver «El borde».
$middleware->trustProxies(
at: '*',
headers: Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_PROTO
| Request::HEADER_X_FORWARDED_PORT,
);
// Global y al final del stack global: así todo el pedido ve el host y la IP del borde.
$middleware->append(\Funnelchat\PlatformGate\Http\Middleware\TrustEdge::class);
$middleware->appendToGroup('api', \Funnelchat\PlatformGate\Http\Middleware\PlatformGate::class);
})
->withExceptions(function (Exceptions $exceptions) {
// El 401 de `api/*`, igual en todos los dominios.
\Funnelchat\PlatformGate\Http\UnauthenticatedResponse::register($exceptions);
})
// config/platform-gate.php
'domain' => 'midominio',
// La superficie de las keys: lo único que una key puede alcanzar. Vacía = nada.
'allowed' => [
'api/v1/recurso*',
],
// Rutas que exigen el permiso de envío.
'send' => [
'POST api/v1/recurso/{id}/enviar',
],
// Superficie amplificada: una llamada, N efectos. Ningún permiso la habilita.
'denied' => [
'POST api/v1/recurso/{id}/ejecutar',
],
// Rutas que piden un prefijo de permiso propio en vez del dominio.
'permission_prefix' => [
'api/v1/webhooks*' => 'webhooks',
],
use Funnelchat\PlatformGate\Caller\CallerContext;
use Funnelchat\PlatformGate\Caller\CallerKind;
$caller = app(CallerContext::class)->get();
// `match` SIN rama default, a propósito: cuando el enum crezca, esto tira
// UnhandledMatchError en tus tests en vez de elegir en silencio.
$failClosed = match ($caller->kind) {
CallerKind::ApiKey => true,
CallerKind::Web => false,
CallerKind::Unverified => false,
};
use Funnelchat\PlatformGate\Http\RequestId;
$id = app(RequestId::class)->for($request); // decide si hace falta; siempre el mismo
$id = RequestId::of($request); // el ya decidido, o null
use Funnelchat\PlatformGate\Usage\CreatedResource;
public function store(StoreMessageRequest $request): JsonResponse
{
$message = $this->messages->send($request->validated());
CreatedResource::declare('message', $message->id);
return response()->json(new MessageResource($message), 201);
}
CreatedResource::declare(string $type, int|string $id): void
CreatedResource::current(): ?CreatedResource // lo declarado en este pedido