webman 中实现 oauth2.0 必须使用封装客户端库并严格对齐其生命周期机制:启用且正确排序 sessionmiddleware,每次请求新建 provider 实例,redirect_uri 须与平台配置逐字一致,state 校验与 token 获取需原子化,token 必须通过 $request->session()->put() 存储,国内平台需校验字段存在性。

Webman 中实现 OAuth2.0 认证,不能靠手拼 URL、硬编码 state 或直接写 curl 换 token —— 这类操作大概率触发 invalid_grant、redirect_uri_mismatch,甚至埋下 CSRF 漏洞。必须用封装好的客户端库,并严格对齐 Webman 的生命周期机制。
必须启用 SessionMiddleware 且顺序正确
Webman 默认不启动 session,$_SESSION 不可用,任何依赖 session 的 OAuth 流程(比如存 state、存 token)都会静默失败。
- 检查
config/middleware.php是否已注册Webman\Middleware\SessionMiddleware::class - 该中间件必须放在路由中间件(如
Webman\Route\Middleware::class)之前,否则$request->session()在控制器里取不到实例 - 别在
config/session.php里改cookie_lifetime却忽略gc_maxlifetime,PHP session 清理依赖后者,设太小会导致刚存的state下次请求就没了
客户端必须按需构建,不能全局单例
把 League\OAuth2\Client\Provider\GitHub 实例写在 config/oauth2.php 里并 return new,会导致所有请求共用同一个 state,彻底失去防 CSRF 能力。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 每次授权请求前,在控制器方法内新建 provider 实例:
$provider = new \League\OAuth2\Client\Provider\GitHub([...]) -
redirect_uri参数必须和第三方平台后台配置**逐字一致**:协议、端口、路径、末尾斜杠都不能差,例如填了http://localhost:8080/callback/就不能在平台填http://localhost:8080/callback - 微信等非标平台要显式传
urlAuthorize(含#wechat_redirect后缀)和scope(如snsapi_login),否则回调拿不到 code
回调路由里 state 校验和 token 换取必须原子化
回调入口第一行没做 state 检查,或比对后没立刻清除 session,就会让攻击者重放 code。
- 开头先判断:
if (!$request->get('state')) { return response()->status(400); } - 从 session 读取时用
$request->session()->get('oauth2_state'),不是$_SESSION;比对后立即$request->session()->forget('oauth2_state') -
$provider->getAccessToken('authorization_code', [...])的参数数组里,code和redirect_uri必须和授权请求时完全相同,否则返回{"error":"invalid_grant"} - 微信返回的
access_token没有expires_in字段,得手动补:'expires_in' => 7200, 'expires_at' => time() + 7200,否则后续isExpired()判断永远为 false
token 存储失败的根本原因不是配置错,而是生命周期错位
直接 $_SESSION['token'] = $token 看似成功,但下个请求就读不到 —— 不是 session 配置问题,是 Webman 响应阶段没触发 session write。
- 务必用
$request->session()->put('access_token', $token),它会触发底层session_write_close() - 不要在中间件里提前调
$response->withCookie()并返回,这会中断后续 session 写入流程 - 若要用 Cookie 存 token,得确保 Cookie 的
path和domain与当前请求匹配,且secure和httpOnly按生产环境要求设置
最易被忽略的一点:微信、QQ 等国内平台返回的用户字段名不统一(比如 openid vs unionid),且部分字段仅在特定 scope 下返回;没校验字段存在性就直接取值,会导致 PHP Notice 或空用户数据。










