定制 graphene-ict/laravel-cognito-guard 二次开发

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

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

graphene-ict/laravel-cognito-guard

Composer 安装命令:

composer require graphene-ict/laravel-cognito-guard

包简介

Lean Laravel auth guard that validates AWS Cognito User Pool JWTs. Supports DB-backed users, DB-less mode, cognito:groups → Gates bridge, multi-pool, and Octane.

README 文档

README

CI codecov Packagist Version Packagist Downloads PHP Version Laravel Version License

A lean Laravel auth guard that validates JSON Web Tokens issued by an AWS Cognito User Pool. Verifies the JWT signature against Cognito's JWKS, enforces standard Cognito claims, and resolves the authenticated user via a UserProvider — or returns a value object in DB-less mode.

Requirements

  • PHP 8.3+
  • Laravel 11 / 12
  • A configured AWS Cognito User Pool

Installation

You can install the package via Composer:

composer require graphene-ict/laravel-cognito-guard

Publish the config file:

php artisan vendor:publish --tag=cognito-guard-config

Set the env vars:

COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
AWS_REGION=us-east-1
# Optional comma-separated allow-list:
COGNITO_CLIENT_IDS=app-client-1,app-client-2

Usage

DB-backed users (default)

  1. Add provider_id to your users table:

    $table->string('provider_id')->unique()->nullable();
  2. Add provider_id to the model's $fillable.

  3. Register the guard in config/auth.php:

    'guards' => [
        'cognito' => [
            'driver' => 'cognito',
            'provider' => 'cognito',
            'pool' => 'default',
        ],
    ],
    
    'providers' => [
        'cognito' => ['driver' => 'cognito'],
    ],
  4. Protect routes:

    Route::middleware('auth:cognito')->get('/me', fn () => auth()->user());

A new User record is auto-provisioned on the first authenticated request whose sub is not yet known. Disable by setting cognito-guard.user_provider.auto_provision to false.

DB-less mode

For SPA / service-to-service callers that don't need a local users table:

'guards' => [
    'cognito' => [
        'driver' => 'cognito',
        'provider' => 'cognito',
        'pool' => 'default',
        'db_less' => true,
    ],
],

auth()->user() returns a GrapheneICT\CognitoGuard\CognitoUser value object:

$user = auth()->user();
$user->username();        // string|null
$user->email();           // string|null
$user->groups();          // string[]
$user->scopes();          // string[]
$user->claim('sub');      // any single claim
$user->claims();          // raw payload (stdClass)

Per-route scope enforcement

Pool-wide required_scopes is a blunt instrument — every route on the guard demands the same scopes. For finer control, use the cognito.scope middleware:

Route::middleware(['auth:cognito', 'cognito.scope:read:reports'])->get('/reports', ...);
Route::middleware(['auth:cognito', 'cognito.scope:read:reports,write:reports'])->post('/reports', ...);

401 if unauthenticated, 403 if any required scope is missing from the token's scope claim.

Groups → Gates bridge

With cognito-guard.bridge_groups_to_gates enabled (default), entries in the cognito:groups claim become Gate abilities for free:

Gate::allows('admins');                       // true if 'admins' is in cognito:groups
Route::middleware('can:moderators')->...;     // works the same

Multi-pool

// config/cognito-guard.php
'pools' => [
    'default'  => ['user_pool_id' => env('COGNITO_USER_POOL_ID'),  'region' => 'us-east-1'],
    'partners' => ['user_pool_id' => env('PARTNER_POOL_ID'),       'region' => 'us-east-1'],
],

// config/auth.php
'guards' => [
    'cognito'  => ['driver' => 'cognito', 'provider' => 'cognito', 'pool' => 'default'],
    'partners' => ['driver' => 'cognito', 'provider' => 'cognito', 'pool' => 'partners'],
],

Recipes

Configuration reference

See config/cognito-guard.php. Key knobs:

  • pools.<name>.allowed_token_use['access'], ['id'], or both.
  • pools.<name>.allowed_client_ids — empty = accept any; populated = strict allow-list against client_id (access) / aud (id).
  • pools.<name>.required_scopes — every scope must be present in the token's scope claim.
  • pools.<name>.leeway — clock-skew tolerance for exp/nbf/iat, in seconds.
  • jwks.cache_ttl — JWKS cache TTL (default 6h). Stale entries kept 30d and used on Cognito outages.
  • bridge_groups_to_gates — toggle the cognito:groups → Gate bridge.
  • user_provider.sub_claim — which JWT claim supplies the stable identifier. Default sub. Set to cognito:username or a custom attribute when a legacy users table is keyed by something other than the Cognito sub.
  • user_provider.sub_column — the column on the user model that stores the value above (default provider_id).

Events

The guard dispatches two events for observability — listen for them however you wire listeners normally (e.g. in AppServiceProvider::boot()):

  • GrapheneICT\CognitoGuard\Events\CognitoTokenValidated — fired after a JWT is verified and a user is resolved. Carries $user, $claims (stdClass), and $pool.
  • GrapheneICT\CognitoGuard\Events\CognitoTokenRejected — fired when a token fails verification, just before the InvalidTokenException propagates. Carries $exception and $pool.

Raw tokens are intentionally excluded from event payloads — log claims, not credentials.

Diagnostics

php artisan about                          # shows the Cognito Guard section
php artisan cognito:test-token <jwt>       # validates a token + prints a step-by-step diagnosis
php artisan cognito:warm-jwks              # pre-fetch JWKS at deploy time

The cognito:test-token command accepts the raw JWT or a Bearer <jwt> string and prints which validation step passed or failed (signature, issuer, token_use, client_id/aud, scopes, expiry). Add --pool=<name> to test against a non-default pool, or --verbose-claims to dump the full payload.

cognito:warm-jwks pre-fetches and caches the JWKS for every configured pool so the first authenticated request after a cold cache doesn't pay the round-trip, and so reachability to cognito-idp.<region>.amazonaws.com is verified at deploy time. Use --pool=<name> to warm a single pool.

FAQ

InvalidTokenException: Invalid token_use "id". Allowed: access

Your guard is configured to accept access tokens only, but the client is sending an id token. Either send an access token, or widen cognito-guard.pools.<name>.allowed_token_use to ['access', 'id'] (the default).

InvalidTokenException: Token client_id/aud is not in the allow-list

The token's client_id (access tokens) or aud (id tokens) doesn't match COGNITO_CLIENT_IDS. Either add the App Client ID to that env var (comma-separated), or leave allowed_client_ids empty to accept any client.

InvalidTokenException: Invalid issuer

The token was issued by a different User Pool. Check COGNITO_USER_POOL_ID and AWS_REGION.

InvalidTokenException: Token has expired

Either the token genuinely expired, or your server clock has drifted. Bump cognito-guard.pools.<name>.leeway (seconds) to tolerate minor skew — but fix the underlying NTP issue, don't paper over it long-term.

JwksFetchException: Failed to fetch JWKS from https://cognito-idp.<region>.amazonaws.com/...

Your app can't reach Cognito's JWKS endpoint. Check egress to cognito-idp.<region>.amazonaws.com. The guard will serve from stale cache for up to 30 days if the JWKS was ever fetched successfully (toggle via cognito-guard.jwks.stale_on_error).

The user returned from auth()->user() isn't my Eloquent model

If your guard config has 'db_less' => true, the package returns a CognitoUser value object built from JWT claims instead of looking up a database row. Set db_less => false (the default) and configure cognito-guard.user_provider.model to point at your Eloquent user model.

Auth provider "..." is not configured

You set 'provider' => 'cognito' on the guard but didn't add a cognito entry under auth.providers. Add:

'providers' => ['cognito' => ['driver' => 'cognito']],
Multiple Cognito pools — how do I authenticate against the second one?

Register a second guard with a different pool key and pick which one to apply per route:

'guards' => [
    'cognito'  => ['driver' => 'cognito', 'provider' => 'cognito', 'pool' => 'default'],
    'partners' => ['driver' => 'cognito', 'provider' => 'cognito', 'pool' => 'partners'],
],

Then Route::middleware('auth:partners')->....

Testing your app

The guard exposes an actingAs() helper so your test suite doesn't need to forge JWTs:

use Illuminate\Support\Facades\Auth;

// DB-less: pass JWT claims, get a CognitoUser back.
Auth::guard('cognito')->actingAs([
    'sub' => 'user-uuid',
    'email' => 'alice@example.com',
    'cognito:groups' => ['admins'],
]);

// DB-backed: pass your Eloquent user + the claims you want attached
// (so the groups → Gates bridge sees them).
Auth::guard('cognito')->actingAs($user, ['cognito:groups' => ['editors']]);

After the call, auth()->user(), auth()->id(), Gate::allows('admins'), and routes behind auth:cognito all behave as if a real token had been verified.

Testing the package

composer install
composer test
composer analyse

Upgrading from v1

Breaking changes — see UPGRADING.md.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

graphene-ict/laravel-cognito-guard 适用场景与选型建议

graphene-ict/laravel-cognito-guard 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10 次下载、GitHub Stars 达 3, 最近一次更新时间为 2022 年 09 月 25 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「Authentication」 「laravel」 「jwt」 「guard」 「oidc」 「GrapheneICT」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

围绕 graphene-ict/laravel-cognito-guard 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 10
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 17
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-09-25