tonka/spark 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

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

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-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])

统计信息

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

GitHub 信息

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

其他信息

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

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固