
后端认证鉴权【免费下载链接】oauth2-serverA spec compliant, secure by default PHP OAuth 2.0 Server项目地址https://gitcode.com/gh_mirrors/oa/oauth2-server点击查看免费下载oauth2-server 是一款遵循规范、默认安全的 PHP OAuth 2.0 授权与资源服务器库从 2013 年的 1.0.0 一路演进到 9.4.0其 CHANGELOG.md 完整记录了每一次新增、修复与破坏性变更。本文以该 CHANGELOG 为主体骨架逐版本解读 oauth2-server 的核心能力演进Device Code Grant 的引入与修复、refresh token 轮换策略、PKCE 强化、密钥管理与 PHP 版本支持变迁并结合仓库源码给出可验证的实现细节。读完本文你将理解每个大版本改了什么、为什么改并能据此规划升级路径与安全加固策略。版本管理规范Keep a Changelog 与 Semantic Versioning仓库 CHANGELOG.md 开篇即声明两条约定格式基于 Keep a Changelog1.0.0 版本起采用——每个版本按Added、Changed、Deprecated、Removed、Fixed、Security分类记录变更版本号遵循 Semantic VersioningSemVer 2.0.0——主版本号变更即代表破坏性变更。这一约定从 7.0.02018 年起正式采用此前1.x ~ 6.x的 CHANGELOG 采用更随意的条目式记录。理解这一规范是读懂后续所有版本条目的前提凡是9.0.0、8.0.0这类主版本号变更都意味着接口层面存在不兼容改动。版本演进总览九个大版本的技术脉络纵观 CHANGELOGoauth2-server 的演进可划分为四个阶段阶段版本区间时间跨度主题1.x ~ 4.x2013 ~ 2014存储接口重构、PDO 驱动、会话模型规范化早期架构奠基5.0.02016-04-17完整代码重写AuthorizationServer / ResourceServer 分家6.x ~ 7.x2017 ~ 2019PKCE、密钥安全、事件系统、静态分析规范合规与工程化8.x ~ 9.x2019 ~ 2026JWT 强化、Device Code Grant、类型系统收紧现代化与长期维护从 composer.json 的require可以看到当前版本9.4.0的运行环境PHP~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0、lcobucci/jwt ^5.6、league/uri ^7.8、psr/http-message ^2.0、defuse/php-encryption ^2.4。9.4.02026-06-14授权请求校验前置与 Scope 最终化完善9.4.0 是本 CHANGELOG 记录的最近一个正式版本包含三处值得注意的变更response_type 参数校验前置此前AuthorizationServer::validateAuthorizationRequest()会先遍历已启用的 grant 类型逐个询问canRespondToAuthorizationRequest()来判断应使用哪个 grant。9.4.0 将requiredresponse_type参数校验前置在确定 grant 类型之前就检查该参数是否存在。当前实现可在 src/AuthorizationServer.php 中看到public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface { if (!isset($request-getQueryParams()[response_type])) { throw OAuthServerException::invalidRequest(response_type); } foreach ($this-enabledGrantTypes as $grantType) { if ($grantType-canRespondToAuthorizationRequest($request)) { return $grantType-validateAuthorizationRequest($request); } } throw OAuthServerException::unsupportedGrantType(); }这意味着缺少response_type的请求会稳定地返回invalid_request错误HTTP 400见 src/Exception/OAuthServerException.php而不是落到unsupported_grant_type分支。Refresh Grant 的 finalizeScopes 现在携带 User ID9.4.0 将User ID 传入 Refresh Grant 的finalizeScopes()调用。finalizeScopes是ScopeRepositoryInterface提供给开发者最终确认/增删 scope的钩子签名见 src/Repositories/ScopeRepositoryInterface.php此前在 Refresh Token Grant 中调用时不传用户标识。当前 src/Grant/RefreshTokenGrant.php 的实现是$userId $oldRefreshToken[user_id]; if (is_int($userId)) { $userId (string) $userId; } $scopes $this-scopeRepository-finalizeScopes($scopes, $this-getIdentifier(), $client, $userId);这一改动让按用户维度做 scope 收敛/扩展的仓库实现成为可能也呼应了 9.1.0 中旧 refresh token 的 user_id 可能是 int的兼容修复。PHP 8.1 支持移除9.4.0 移除了对 PHP 8.1 的支持。结合 composer.json 的require约束~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0当前版本要求 PHP 8.2。9.3.02025-11-25敏感参数保护与 Bearer 头大小写合规SensitiveParameter 属性9.3.0 引入sensitive parameter避免敏感数据出现在堆栈追踪中。这在仓库中体现为大量#[SensitiveParameter]注解例如 src/CryptKey.php 对passPhrase构造参数、src/AuthorizationServer.php 对privateKey与encryptionKey构造参数、以及 src/RequestAccessTokenEvent.php 对accessToken属性均做了标记。这意味着即使异常被抛出并打印追踪密钥与 token 内容也不会泄露。Bearer header 大小写不敏感9.3.0 修复了 Bearer 头匹配按规范Authorization头值中的 scheme 应大小写不敏感。当前 src/AuthorizationValidators/BearerTokenValidator.php 的正则为$jwt trim((string) preg_replace(/^\s*Bearer\s/i, , $header[0]));正则末尾的i修饰符使Bearer、bearer、BEARER均能正确匹配。类似地src/Grant/AbstractGrant.php 中 HTTP Basic 认证也使用stripos($header, Basic ) ! 0做大小写不敏感判断。PHP 8.5 支持9.3.0 新增对 PHP 8.5 的支持。9.2.02025-02-15supportsGrantType 与 Device Code 轮询修复ClientTrait 新增 supportsGrantType9.2.0 为内置的ClientTrait增加了supportsGrantType方法使授权服务器能在客户端无权使用某 grant 类型时返回unauthorized_client错误对应 src/Exception/OAuthServerException.phpHTTP 400。当前 src/Entities/Traits/ClientTrait.php 中的默认实现返回true默认放行所有 grant开发者可在自己的ClientEntity中覆写它做白名单控制。而 src/Grant/AbstractGrant.php 的getClientEntityOrFail()与supportsGrantType()构成了完整的授权检查链protected function supportsGrantType(ClientEntityInterface $client, string $grantType): bool { return method_exists($client, supportsGrantType) false || $client-supportsGrantType($grantType) true; }另外9.2.0 起Refresh、Device Code、Password 三种 grant 仅在客户端是 confidential机密型时才校验客户端凭据。这与 src/Grant/AbstractGrant.php 的validateClient()逻辑一致if ($client-isConfidential())才要求client_secret并通过validateClient()校验。Device Code Grant 的三处轮询 bug 修复9.2.0 对 Device Authorization Grant 的轮询逻辑做了集中修复见 src/Grant/DeviceCodeGrant.phpinterval 可见性开关 bugsetIntervalVisibility()此前存在状态处理问题slow_down 轮询时间未持久化此前因slow_down异常在persistDeviceCode之前抛出导致新的轮询时间未被保存。修复后先更新lastPolledAt并持久化再抛slow_down或authorization_pending用户已完成授权后仍返回 slow_down此前即使设备码已被用户批准/拒绝轮询仍可能误报slow_down。修复后respondToAccessTokenRequest()先判断getUserIdentifier()是否已绑定——未绑定才进入 pending/slow_down 分支已绑定则直接走批准或拒绝路径。轮询节流的判定逻辑在 src/Grant/DeviceCodeGrant.phpprivate function deviceCodePolledTooSoon(?DateTimeImmutable $lastPoll): bool { return $lastPoll ! null $lastPoll-getTimestamp() $this-retryInterval time(); }事件细分ACCESS_TOKEN_ISSUED 与 REFRESH_TOKEN_ISSUED9.2.0 起Device Code Grant 在签发 access/refresh token 时改发专门的RequestAccessTokenEvent与RequestRefreshTokenEvent而非笼统的RequestEvent。见 src/Grant/DeviceCodeGrant.php这两类事件分别携带 token 实体src/RequestAccessTokenEvent.php、src/RequestRefreshTokenEvent.php事件名称常量定义在 src/RequestEvent.php。Windows 下密钥权限检查跳过9.2.0 起无论用户如何选择Windows 平台上均跳过密钥文件权限检查因为该检查在该操作系统上无法可靠执行。这与 src/CryptKey.php 中if ($keyPermissionsCheck true PHP_OS_FAMILY ! Windows)的条件一致。9.1.02024-11-21错误语义修正与旧数据兼容Auth Code 无效时返回 invalid_grant9.1.0 修正了 Auth Code Grant 的错误语义当使用无效的授权码请求 access token 时此前返回invalid_request现在改为返回invalid_grant两者都是 HTTP 400但错误类型不同见 src/Exception/OAuthServerException.php 与 src/Exception/OAuthServerException.php。当前 src/Grant/AuthCodeGrant.php 在授权码解码失败时抛出invalid_grant(Cannot validate the provided authorization code)。Device Code 请求不再要求 scope 参数9.1.0 修复了规范合规问题此前 Device Code 的 access token 请求被错误地要求携带 scopes。规范中 scope 应在设备授权请求阶段完成协商而非 token 交换阶段。src/Grant/DeviceCodeGrant.php 的 token 请求流程不再读取scope参数而是使用设备码实体中已绑定的 scopes 调用finalizeScopes()。旧 refresh token 的 int user_id 兼容由于 9.0.0 之前签发的 refresh token 中user_id可能存为整数9.1.0 起在 src/Grant/RefreshTokenGrant.php 增加了is_int($userId)判断并强转为字符串避免旧 token 被错误拒绝。PHP 8.4 支持9.1.0 新增对 PHP 8.4 的支持。9.0.x9.0.0 发布后的三轮紧急修复9.0.0 是包含 Device Code Grant 的大版本随后的 9.0.1 集中修复了四个问题全部可在 9.0.0 代码基础上验证事件发射器持久化此前每次请求都会重新生成 emitter现在自动生成的 emitter 被持久化见 src/AuthorizationServer.php 中setEmitter($this-getEmitter())的注入机制redirect_uri 可省略修复了即便授权请求阶段未指定 redirect_uri也无法省略该参数的问题——相关判断见 src/Grant/AuthCodeGrant.php仅当授权码载荷中存在redirect_uri时才要求该请求必须携带state 参数完整性修复了invalid_scope错误响应缺失state以及 Implicit Grant 的access_denied重定向 fragment 中缺失state的问题revokeRefreshTokens(false) 语义修复了关闭 refresh token 撤销会连带禁用新 refresh token 签发的问题。当前 src/AuthorizationServer.php 的revokeRefreshTokens()与 src/Grant/AbstractGrant.php 对应而 src/Grant/RefreshTokenGrant.php 中只在$this-revokeRefreshTokens为真时才撤销旧 token签发新 token 的逻辑不受影响。9.0.02024-05-13现代化大版本的能力全景9.0.0 是本仓库近十年来最重要的主版本CHANGELOG 列出的大量条目均能在当前源码中直接找到落点Device Authorization GrantRFC 86289.0.0 新增 Device Authorization GrantPR #1074这是面向无头设备智能电视、打印机、IoT的授权流程。核心实现位于 src/Grant/DeviceCodeGrant.php配套的响应类型是 src/ResponseTypes/DeviceCodeResponse.php仓储接口是 src/Repositories/DeviceCodeRepositoryInterface.php。DeviceCodeGrant构造函数src/Grant/DeviceCodeGrant.php接收设备码 TTL、verification_uri与可选的重试间隔retryInterval默认 5 秒其 grant 标识为urn:ietf:params:oauth:grant-type:device_code。服务器通过 src/AuthorizationServer.php 的respondToDeviceAuthorizationRequest()与completeDeviceAuthorizationRequest()处理设备授权请求与用户确认。generateUserCode()src/Grant/DeviceCodeGrant.php生成的用户码从BCDFGHJKLMNPQRSTVWXZ去掉易混淆字母中随机选取默认 8 位方便用户手动输入。GrantTypeInterface 新契约revokeRefreshTokens()9.0.0 为 src/Grant/GrantTypeInterface.php 新增revokeRefreshTokens(bool $willRevoke)用于控制refresh token 使用后是否立即撤销即轮换开关。这一机制贯穿所有 grantAuthorizationServer在enableGrantType()时统一注入src/AuthorizationServer.php。CryptKeyInterface密钥实现的解耦9.0.0 引入 src/CryptKeyInterface.php允许开发者替换默认的 src/CryptKey.php 密钥实现。接口要求三个方法getKeyPath()、getPassPhrase()、getKeyContents()。AuthorizationServer构造函数接受CryptKeyInterface|string类型的私钥src/AuthorizationServer.php字符串会内部包装为CryptKey。finalizeScopes 全面扩展9.0.0 起授权服务器支持在client 使用 refresh token 时也执行 scope 最终化且finalizeScopes()的参数可携带 auth code ID见 src/Repositories/ScopeRepositoryInterface.php 的$authCodeId参数。src/Grant/AuthCodeGrant.php 中可以看到传入$authCodePayload-auth_code_id的调用。AuthorizationRequestInterface 与工厂方法9.0.0 引入 src/RequestTypes/AuthorizationRequestInterface.php并通过工厂方法createAuthorizationRequest()创建请求对象见 src/Grant/AbstractAuthorizeGrant.php使扩展AuthorizationRequest更加容易。严格类型与请求参数字符串化9.0.0 的两项工程级变更所有接口的参数与返回值全部声明类型强制严格类型declare(strict_types1)贯穿整个 src/ 目录请求参数在库内部统一解析为字符串见 src/Grant/AbstractGrant.php 的parseParam()非标量参数值会抛出invalid_request。AccessTokenEntityInterface 改用 toString()9.0.0 要求AccessTokenEntityInterface实现toString()方法而非魔术方法__toString()见 src/Entities/AccessTokenEntityInterface.php配合setPrivateKey()让实体自身具备输出 JWT 的能力。错误响应的规范收敛9.0.0 从 OAuthException 的 HTTP 响应中移除了message属性仅保留规范要求的error_description。这与此前 7.3.3 中新增error_description、message将在下个大版本移除的弃用预告Deprecated形成闭环——CHANGELOG 展示了 7.3.3 预告与 9.0.0 落实的完整链条。错误码语义修正9.0.0 修复了 refresh token 校验错误语义过期、被撤销、无法解密或不属于当前 client 的 refresh token一律返回invalid_grantHTTP 400而非此前错误的invalid_requestHTTP 401。当前 src/Grant/RefreshTokenGrant.php 的validateOldRefreshToken()与 src/Exception/OAuthServerException.php 的invalidRefreshToken()均已对齐该语义。8.x 时代PKCE 强化、JWT 校验与安全公告8.0.0 ~ 8.5.42019 ~ 2023确立了现代 oauth2-server 的形态这一阶段的安全相关条目密度极高8.0.0公开客户端与 PKCE 制度化公开客户端public clients可以使用 Auth Code Grant此前仅限机密客户端requireCodeChallengeForPublicClients标志拒绝未提供 code challenge 的公开客户端见 src/Grant/AuthCodeGrant.php并可通过disableRequireCodeChallengeForPublicClients()关闭src/Grant/AuthCodeGrant.php取消enableCodeExchangeProof开关任何客户端只要发送code_challenge就会自动触发 PKCE 校验无需显式开启isConfidentialgetter 与validateClient()拆分客户端类型识别src/Entities/Traits/ClientTrait.php与客户端校验职责分离getClientEntityOrFail()包装器见 src/Grant/AbstractGrant.php确保仓储未返回客户端实体时统一抛异常并触发事件Client Credentials Grant 仅限机密客户端与 OAuth2 规范对齐该限制在 8.1.0 中进一步明确__toString()取代convertToJWT()实体输出 JWT 的接口由AccessTokenEntityInterface统一收敛9.0.0 进一步改为toString()移除 JTI claim从 JWT header 中移除 JTI。8.3.0 ~ 8.4.0安全与规范细节redirect_uri 按 RFC 8252原生 App OAuth校验事件携带 token 载荷RequestAccessTokenEvent/RequestRefreshTokenEvent开始包含 access/refresh token 实体revokeRefreshTokens()决定刷新令牌使用后是否撤销这一 API 在 9.0.0 中被提升为GrantTypeInterface契约密钥用openssl_pkey_get_private()/openssl_pkey_get_public()验证取代正则匹配——见 src/CryptKey.php 的isValidKey()同时支持 RSA 与 EC 密钥8.4.0 引入 JWT 校验的时间漂移 leewayBearerTokenValidator构造函数的$jwtValidAtDateLeewaysrc/AuthorizationValidators/BearerTokenValidator.php用于容忍服务器间时钟偏差8.4.0 阻断 PKCE 降级攻击token 请求携带code_verifier但授权码未绑定code_challenge时直接拒绝——当前逻辑在 src/Grant/AuthCodeGrant.phpif (!isset($authCodePayload-code_challenge) $codeVerifier ! null) { throw OAuthServerException::invalidRequest( code_challenge, code_verifier received when no code_challenge is present ); }8.3.x 的安全公告8.5.3修复私钥口令无效时LogicException泄露密钥字符串的问题——src/CryptKey.php 中passPhrase已被标记#[SensitiveParameter]8.3.3移除lcobucci/jwt中被 GHSA 安全公告弃用的LocalFileReference()。8.1.x ~ 8.2.x密钥处理的细节修正8.2.x 连续修复了私钥口令未正确传递给 JWT 库的问题8.2.1、8.2.28.3.2 起密钥始终保存在内存中不再写入 /tmp 临时文件并简化了 bearer token 的正则匹配。7.x 时代事件系统、静态分析与 PKCE 落地7.0.0引入PHPStan 静态分析并逐步提升到 level 7见 7.1.0修复 PKCE 实现7.0.0 之前 PKCE 有缺陷修复 S256 code challenge 方法支持 CRLF 行尾的 RSA 密钥对应测试密钥见 tests/Stubs/private.key.crlf7.1.0新增access/refresh token 签发事件发射器对应 src/RequestAccessTokenEvent.php 与 src/RequestRefreshTokenEvent.php支持Defuse\Crypto\Key加速密钥加解密7.3.0finalizeScopes()调用点从validateAuthorizationRequest移到completeAuthorizationRequest——即在即将签发 access token 之前才执行 scope 最终化修正了 AuthorizationServer 的状态性无状态化修复7.4.0RefreshTokenRepository可以返回null使 refresh token 变为可选项——对应 src/Grant/AbstractGrant.php 的issueRefreshToken()中if ($refreshToken null) return null;的分支。6.x 时代安全审计与密钥管理转折5.1.42017Mozilla Secure Open Source Fund 资助的安全审计后发布安全修复版本官方建议所有用户尽快升级推荐为每个AuthorizationServer实例调用setEncryptionKey()6.0.02017破坏性变更——AuthorizationServer构造函数从公钥改为加密密钥字符串移除 HHVM 与 PHP 5.5 支持6.1.0Implicit Grant 的 token 类型从bearer改为规范要求的Bearer授权端点新增默认 scope 支持强制授权请求只能携带一个 redirect_uri。5.x 时代v5 完整重写确立的架构CHANGELOG 明确记载5.0.0 是一次完整的代码重写complete code rewrite其确立的架构沿用至今Server类更名为AuthorizationServer见 src/AuthorizationServer.php新增ResourceServer类并演化为 PSR-7 中间件见 src/ResourceServer.php 与 src/Middleware/ResourceServerMiddleware.phpJWT 支持与PSR-7 支持术语统一所有Storage更名为Repository内置实体被移除改为Traits 供快速复用见 src/Entities/Traits/ 目录下的AccessTokenTrait、ClientTrait、ScopeTrait等移除 MAC token 输出类型保留 Bearer token 输出类型5.1.0 实现RFC 7636PKCE并新增唯一 access token 约束冲突检查对应 src/Exception/UniqueTokenIdentifierConstraintViolationException.php在 src/Grant/AbstractGrant.php 的issueAccessToken()中体现为重试机制。更早版本1.x ~ 4.x基础能力奠基CHANGELOG 记录了一些至今仍可追溯的设计决策4.1.0加入 MAC token 支持后被 5.0 移除、refresh token 轮换开关rotateRefreshTokens()3.0.0所有 grant 支持自定义 access token TTL对应今日 src/AuthorizationServer.php 的enableGrantType($grantType, $accessTokenTTL)签名移除内置 DB 提供器2.0.0授权码默认 TTL 10 分钟、refresh token 默认 TTL 一周对应今日AuthCodeGrant构造参数$authCodeTTL与 src/Grant/RefreshTokenGrant.php 的P1M默认值Client Credentials Grant 不再签发 refresh token1.0.x增加requireStateParam()与requireScopeParam()等基础校验能力。PHP 版本支持矩阵跟随语言演进的取舍CHANGELOG 中 PHP 版本支持的变化频率很高整理如下便于评估升级约束版本新增支持移除支持5.0.0PHP 5.5.9最低—6.0.0—PHP 5.5、HHVM7.0.0—PHP 5.6、5.x/6.x 库版本8.0.0—PHP 7.08.1.0PHP 7.4PHP 7.18.5.0PHP 8.1、8.2PHP 7.2、7.3、7.49.0.0—配合严格类型化9.1.0PHP 8.4—9.3.0PHP 8.5—9.4.0—PHP 8.1当前 composer.json 明确要求~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0。升级路径与验证建议基于 CHANGELOG 的版本依赖关系可从三条线索制定升级与验证策略从 8.x 升 9.x优先关注破坏性变更——接口全部严格类型化、AuthorizationRequest改用工厂方法、AccessTokenEntityInterface改为toString()、错误响应移除message属性。建议对照 src/RequestTypes/AuthorizationRequestInterface.php 与 src/Entities/AccessTokenEntityInterface.php 逐项适配安全项优先CHANGELOG 中标注 Security 的条目8.3.3、8.4.0、8.5.3、5.1.4应在升级后立即通过测试回归确认尤其是 PKCE 降级阻断与密钥泄露防护可参照 tests/Grant/AuthCodeGrantTest.php 中的相关用例Device Code 语义回归9.1.0/9.2.0 对 Device Code Grant 的轮询与 scope 语义有多处修正可借助 tests/Grant/DeviceCodeGrantTest.php 的slow_down、authorization_pending、access_denied分支用例验证轮询节流INTERVAL_RATE与事件发射RequestAccessTokenEvent、RequestRefreshTokenEvent行为是否符合预期。结语一份高质量的 CHANGELOG 不只是变更流水账它本身就是一份压缩的技术史。oauth2-server 的 CHANGELOG.md 记录了一条清晰的演进主线从 v5 的架构重写到 v7 引入事件与 PKCE再到 v9 落地 Device Code Grant 与严格类型化——每一次修复都有对应的测试与源码支撑每一个弃用预告如message字段都在下一个大版本中得到落实。对使用者而言读懂这份 CHANGELOG就等于拿到了升级决策与安全加固的完整路线图。赞分享后端认证鉴权【免费下载链接】oauth2-serverA spec compliant, secure by default PHP OAuth 2.0 Server项目地址https://gitcode.com/gh_mirrors/oa/oauth2-server点击查看免费下载相关推荐django-extensions 版本演进全解析从 CHANGELOG 看 Django 扩展生态的十年变迁django extensions 版本演进全解析从 CHANGELOG 看 Django 扩展生态的十年变迁 Django Extensions 是 Dja后端开发工具Matter.js 版本演进全解析从 CHANGELOG 看 2D 物理引擎十年技术变迁0.5 → 0.20Matter.js 版本演进全解析从 CHANGELOG 看 2D 物理引擎十年技术变迁0.5 → 0.20 本篇技术指南以仓库根目录的 CHANGELO物理引擎游戏开发Foreman 版本演进全解析从 Changelog 看 Procfile 进程管理器的十年迭代Foreman 版本演进全解析从 Changelog 看 Procfile 进程管理器的十年迭代 Foreman 是一款用于管理 Procfile 型应用进程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考