tonka/spark
最新稳定版本:v1.2.7
Composer 安装命令:
composer require tonka/spark
包简介
Tonka Spark is a PHP library that provides Ziggy-like functionality for Laravel applications, allowing you to generate URLs to named routes in your JavaScript code.
README 文档
README
The secure bridge between your Tonka Framework backend and your frontend router.
Spark is the server-side package responsible for exposing, filtering, and formatting your named routes for the tonka-router package. It features dynamic access control through Policies, allowing you to hide sensitive routes from unauthorized users effortlessly.
🌟 Why use Spark?
Exposing all your backend routes to the browser is a security risk. Spark solves this by giving you fine-grained control over what is visible to the frontend, leveraging your existing Policy classes to determine visibility based on the current user's role.
✨ Features
- 🛡️ Dynamic Access Control: Integrate with your existing Policy classes to show/hide routes (e.g., hide
admin.*from regular users) automatically. - 📦 JSON Output: Generates a structured JSON object ready for JavaScript consumption.
- 🖥️ Template Directive: Injects routes directly into your HTML (via a
data-routesattribute or global variable). - 🔌 Groups: Organize your routes by group (e.g.,
public,auth) and expose them selectively for better performance. - 🚀 Flexible Filtering: Use Whitelist (
only) or Blacklist (except) modes with wildcard support.
⚙️ Configuration
Publish the configuration file:
php tonka spark:config
This will create config/spark.php:
return [ /* |-------------------------------------------------------------------------- | Route Filtering (Whitelist Mode) |-------------------------------------------------------------------------- | By default, no routes are exposed for security. | You must explicitly allow routes. | | You can attach a 'policy' class to any rule. If provided, Spark will | instantiate it and call the authorize() method. If it returns false, | the route will be hidden from the JSON output. */ 'only' => [ // Public routes (accessible to everyone) [ 'name' => 'home', 'policy' => null ], [ 'name' => 'posts.*', // Wildcard support 'policy' => null ], // Protected routes (Only visible if the Policy returns true) [ 'name' => 'users.profile', 'policy' => \App\Contracts\Spark\UserContract::class ], // Admin routes (Only visible if AdminContract authorizes) [ 'name' => 'admin.*', 'policy' => \App\Contracts\Spark\AdminContract::class ], ], /* |-------------------------------------------------------------------------- | Route Filtering (Blacklist Mode) |-------------------------------------------------------------------------- | Use this to expose everything EXCEPT specific patterns. | Policies are also supported here to enforce further restrictions. */ // 'except' => [ // [ // 'name' => '_debugbar.*', // 'policy' => \App\Contracts\Spark\SuperAdminContract::class // ], // ], /* |-------------------------------------------------------------------------- | Groups |-------------------------------------------------------------------------- | Define route groups for selective exposure via @routes('group_name'). */ 'groups' => [ 'public' => ['home', 'about', 'contact'], 'auth' => ['dashboard', 'profile', 'settings'], ], ];
🧭 Groups vs. Policies: Why Use Both?
You might wonder: "If Policies handle security, are Groups necessary?"
The short answer is yes. They serve distinct but complementary purposes:
- Policies (The "Who am I?"): Handle Security. They determine if the current user is authorized to see a specific route (e.g., hiding
admin.*from regular users). - Groups (The "Where am I?"): Handle Context & Performance. They determine which routes are relevant to the current page (e.g., only sending auth routes to the Dashboard page, not the Login page).
Why combine them?
- Performance: Without groups, sending all authorized routes (which could be hundreds) to a simple login page is wasteful. Using groups keeps the JSON payload small and fast.
- Maintainability: Groups allow you to update route lists in one place (
config/spark.php) instead of hardcoding arrays in every Blade file.
🚀 Usage
1. Injection in Views (Recommended)
Use the @routes directive in your main layout.
<!DOCTYPE html> <html> <head> <!-- ... --> </head> <body> @routes('auth') <!-- Or simple @routes (without group)--> @inertia </body> </html>
How it works with Policies:
When the page loads, Spark iterates through your configuration. For every route matching your rules, it checks the associated Policy.
- If the Policy authorizes the request → The route is included in the JSON.
- If the Policy denies the request → The route is excluded.
- If no Policy is defined → The route is included (default behavior).
2. File Generation
Generate a static routes file for SPAs:
php tonka spark:generate
This creates a routes.json file reflecting the current user's permissions.
3. API Endpoint
For dynamic fetching:
Route::get('/api/spark-routes', function () { return \Tonka\Spark\Spark::toJson(); });
🔐 Security Best Practices
- Use Policies for Sensitive Routes: Do not rely solely on frontend hiding. Use the
policykey to ensure backend logic prevents unauthorized routes from ever reaching the browser. - Avoid
exceptif possible: Whitelisting (only) is generally safer than blacklisting (except) for API exposure. - Validate Policy Methods: Ensure your Policy classes have a public
authorize()method that returns a boolean.
📚 Integration with Tonka Router
Once exposed, your frontend consumes the routes seamlessly:
import { route } from 'tonka-router'; // This link will only be generated if the 'admin.users' route was authorized by the backend Policy const url = route('admin.users', { id: 1 }); // Or simply route('admin.users', [1])
统计信息
- 总下载量: 13
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 4
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-02-24