Webman需手动实现OIDC授权码流程:拼接/auth地址跳转、校验state/nonce、用code换token、JWT本地验签、中间件注入用户上下文、调/logout端点协同登出。

Webman 不能直接用 keycloak-spring-boot-starter 或 keycloak-angular 那套配置 —— 它没 Spring Boot 的自动装配,也没 Angular 的模块注入机制。必须手动处理 OIDC 流程、Token 验证和会话同步。
Webman 中如何发起 OIDC 登录跳转
Keycloak 是标准 OIDC 提供方,Webman 要走 Authorization Code Flow,就得自己拼接 /realms/{realm}/protocol/openid-connect/auth 地址。不能依赖框架封装,否则回调地址、state、nonce 都容易出错。
- 必须显式构造 query 参数:
client_id、redirect_uri(需与 Keycloak 后台 Client 的 Valid redirect URIs 完全一致,含协议、端口、路径)、response_type=code、scope=openid -
state必须随机生成并存入 session(防止 CSRF),且在回调时严格校验 -
nonce建议生成并传入,用于绑定 ID Token 的防重放;Keycloak 默认不强制,但企业环境应启用 - 不要硬编码 Keycloak 地址,把
auth-server-url和realm提到 config 文件里,比如config/keycloak.php中定义'url' => 'https://auth.example.com'
回调路由里怎么换 code 换 token
Keycloak 的 /token 接口要求 POST 请求带 client_id、client_secret、code、redirect_uri、grant_type=authorization_code。Webman 没内置 OAuth2 客户端,得用 Co\curl 或 Http\Client 手动发请求。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
-
client_secret必须从 Keycloak Client 的 Credentials 标签页复制,类型为confidential的 Client 才有该字段 - 返回的
access_token和id_token需解析 JWT:用firebase/php-jwt解id_token并校验iss、aud、exp、nonce(注意 Keycloak 的iss是https://auth.example.com/realms/{realm}) - 别把 raw token 存 session —— 至少提取
sub、preferred_username、email等必要字段,避免 session 过大或泄露敏感 claims - 如果要用
refresh_token,记得存它并设好过期时间(Keycloak 默认 1800 秒),但 Webman 无后台定时任务,刷新逻辑得由前端主动触发或登录态快过期时预请求
怎么验证 API 请求里的 Access Token
Webman 作为资源服务器,不代理认证,而是验证每个请求头里的 Authorization: Bearer {token}。Keycloak 不提供实时 introspect 接口(除非开 admin-cli 并配权限),所以推荐用公钥本地验签。
- 从 Keycloak 控制台 Realm Settings → Keys → Public Key 复制 PEM 内容,保存为
config/keycloak.pub - 用
firebase/php-jwt的JWT::decode()配合RS256算法验证,必须校验aud(应为你的 client_id)、exp、iat、iss - 别忽略
azp字段:当 client 使用了service accounts或跨 client 调用时,azp表明实际发起请求的 client,需与aud对齐或白名单校验 - Webman 中建议写个中间件,在
handle()里做 token 解析和用户上下文注入(如$request->withAttribute('user', $payload)),后续控制器可直接取
登出时 Keycloak 与 Webman 怎么协同
单纯销毁 Webman session 不等于登出 Keycloak —— 用户在其他 tab 还能用 access_token 访问资源,SSO 也未真正退出。
- 要调 Keycloak 的 logout endpoint:
GET /realms/{realm}/protocol/openid-connect/logout?id_token_hint={id_token}&post_logout_redirect_uri={redirect} -
id_token_hint必须是原始登录时拿到的id_token(不是 access_token),且未过期;否则 Keycloak 会清 cookie 但不触发 SSO 登出 -
post_logout_redirect_uri必须提前注册在 Client 的Valid Post Logout Redirect URIs列表中 - 登出后,Webman 应清空自己的 session,并重定向到 Keycloak logout 页面,而不是直接跳回首页 —— 否则 SSO 状态残留
Keycloak 的 OIDC 实现细节多,比如 code_challenge_method 默认是 plain(Webman 若对接移动端需切 S256),又比如 realm-level 的 Access Token Lifespan 和 client-level 的 Client Session Idle 两套超时逻辑容易混淆。这些参数不调对,前端反复跳登录页、token 验证莫名失败,都是常见现象,得对着 Keycloak Admin Console 一层层核对。

















