Laravel Passport 现代作用域 – 基于属性的 OAuth 作用域强制执行

发布: (2026年1月8日 GMT+8 07:49)
4 min read
原文: Dev.to

Source: Dev.to

Laravel Passport 传统上在 路由层级 强制 OAuth 范围,通常通过路由文件中的中间件定义实现。虽然可行,但往往导致:

  • 授权规则分散在各个路由中
  • 控制器与基础设施关注点耦合
  • 范围需求重复或难以审查
  • 随着 API 增长,清晰度下降

Laravel Passport Modern Scopes 引入了一种不同的做法。

思路:在需要的地方声明范围

不再把范围写进路由,而是使用 PHP 8 属性 直接在控制器或控制器方法上声明 OAuth 范围需求。授权意图与被保护的代码并列,而 Passport 仍然负责认证和令牌验证。

示例

use N3XT0R\PassportModernScopes\Support\Attributes\RequiresScope;
use N3XT0R\PassportModernScopes\Support\Attributes\RequiresAnyScope;

#[RequiresScope('users:read')]
final class UserController
{
    public function index()
    {
        // Requires users:read
    }

    #[RequiresAnyScope('users:update', 'users:write')]
    public function update()
    {
        // Requires at least one of the given scopes
    }
}

单一中间件在运行时检查控制器属性,并使用 Laravel Passport 原生的 tokenCan 检查来强制执行。认证本身仍由你配置的守卫(例如 auth:api)负责。

本包的功能

  • 支持 基于属性的 OAuth 范围强制
  • 保持路由简洁且不依赖基础设施
  • 使授权需求显式且易于发现
  • 与 Passport 现有的范围验证兼容
  • 无需修改 Passport 内部实现

范围是 声明的,而不是硬接线

为什么使用属性?

  • 声明式、明确
  • 不会在路由和控制器之间出现重复
  • 代码审查时更易理解
  • 友好于静态分析和文档工具
  • 不会在路由定义中散布魔法字符串

这使 授权意图HTTP 接线 分离。

本包不做的事

  • ❌ 不替代 Laravel Passport
  • ❌ 不实现认证
  • ❌ 不引入自定义守卫
  • ❌ 不强制业务规则

它仅解析并强制 声明的 OAuth 范围需求

在架构中的定位

Laravel Passport Modern Scopes 刻意保持小巧聚焦。它与以下组合效果更佳:

  • 结构化的范围模型(如 resource:action
  • 领域层授权逻辑
  • 集中管理范围的后台工具

可以单独使用,也可以与更高级的授权库一起使用。

安装

composer require n3xt0r/laravel-passport-modern-scopes:^2.0

中间件会通过包的服务提供者自动注册。

最后感想

本包关注 清晰度,而非抽象。如果你倾向于:

  • 明确的授权需求
  • 干净的路由
  • 能清晰表达意图的控制器

那么基于属性的范围强制将是一个非常自然的选择。

欢迎提供反馈并参与讨论。

Back to Blog

相关文章

阅读更多 »

使用 DataBlock 探索真实世界 API

比较 Symfony 和 Laravel 使用 GitHub 与 Packagist 数据 在第一篇文章《Handling Nested PHP Arrays Using DataBlock》中,我们探索了 DataBlock 与一个 s...