定制 tonka/spark 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tonka/spark

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-routes attribute 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?

  1. 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.
  2. 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

  1. Use Policies for Sensitive Routes: Do not rely solely on frontend hiding. Use the policy key to ensure backend logic prevents unauthorized routes from ever reaching the browser.
  2. Avoid except if possible: Whitelisting (only) is generally safer than blacklisting (except) for API exposure.
  3. 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])

tonka/spark 适用场景与选型建议

tonka/spark 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 14 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 02 月 24 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 tonka/spark 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 tonka/spark 我们能提供哪些服务?
定制开发 / 二次开发

基于 tonka/spark 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 14
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 41
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-02-24