grazulex/laravel-sharelink
Secure, temporary share links for Laravel. Share files, routes, and model previews with expirations, usage limits, password protection, rate limiting, IP/CIDR filtering, signed URLs, burn-after-reading, and full access auditing.
Install the package via Composer, publish migrations and config, then run migrations:
composer require grazulex/laravel-sharelink
php artisan vendor:publish --tag="sharelink-migrations"
php artisan vendor:publish --tag="sharelink-config"
php artisan migrate
The first use case is generating a temporary link to share a private file. For example, to share a document with a 30-minute expiration and 3 max clicks:
use Grazulex\ShareLink\Facades\ShareLink;
$link = ShareLink::create('storage/app/private/contract.pdf')
->expiresIn(30)
->maxClicks(3)
->generate();
// Send $link->url via email or embed in UI
Check config/sharelink.php to verify the default route prefix (/share) and middleware — you’ll need to route incoming share links, which the package handles automatically via its built-in controller.
File Sharing with Laravel Storage: Use disk-agnostic paths ('s3://bucket/report.pdf' or 'public://invoices/...') — the package respects Laravel’s filesystem abstraction and supports X-Sendfile/X-Accel-Redirect for optimized delivery in production.
Route-Based Sharing: Protect sensitive routes without exposing IDs:
ShareLink::create([
'type' => 'route',
'route' => 'admin.audit.show',
'parameters' => ['id' => 456]
])->expiresIn(60)->generate();
Model Previews: Enable secure preview of model data without direct access:
$link = ShareLink::create([
'type' => 'model',
'class' => User::class,
'id' => $user->id
])->expiresIn(45)->generate();
The model’s toArray() output is serialized and served as JSON upon access.
High-Security Scenarios: Combine password, IP filtering, burn-after-reading, and metadata:
ShareLink::create($sensitivePdf)
->burnAfterReading()
->withPassword('SecurePass!2025')
->metadata(['allowed_ips' => ['10.0.0.0/8']])
->maxClicks(1)
->generate();
CLI & Automation: Use Artisan commands to manage links programmatically:
php artisan sharelink:revoke abc123
php artisan sharelink:prune --days=7
Observability: Hook into events like ShareLinkAccessed, ShareLinkExpired, or ShareLinkRevoked via event listeners to integrate with logging, analytics, or alerting tools (e.g., Slack, Sentry).
Signed URLs are Optional: The ShareLink::signedUrl() method adds a second layer of Laravel signature validation — useful for high-stakes links but not enabled by default. Ensure your frontend doesn’t expect signed URLs unless configured via config/sharelink.php.
Burn-After-Reading ≠ First Request: Burning occurs only after successful access (i.e., correct password if required). Failed attempts (e.g., wrong password) do not consume the burn — verify in tests with dd($link->clicks).
Rate Limiting is Per-Link: Password throttling and general rate limiting apply per share link, not globally. Avoid reusing passwords across many active links — this could trigger local lockouts.
X-Sendfile Requires Server Config: To serve large files efficiently, enable x_accel_redirect or x_sendfile in both config/sharelink.php and your web server (nginx/Apache) — otherwise, the file will stream via PHP (risking memory/timeouts).
Token Safety: Tokens are UUID-based but must be treated as secrets. Never log raw tokens, and use ShareLink::uuid($token) or ShareLink::find($id) for lookups — avoid parsing URLs manually.
Metadata Column: The metadata JSON column supports custom business data (e.g., campaign ID, anonymized IP hash), but avoid storing raw PII unless encrypted at rest. Remember: it’s indexed via JSON path queries (MySQL 5.7+ / PostgreSQL) if needed later.
Testing Tip: In tests, use ShareLink::fake() to bypass DB writes and assert behaviors like URL generation or expiration logic without side effects. Combine with ->withPassword(...) and ->burstAfterReading() to verify security flows.
How can I help you explore Laravel packages today?