资源服务器如何独立于IdP本地验证OAuth2令牌(PHP实现)
答案
资源服务器完全可以做到不每次向IdP发请求就校验SPA携带的令牌有效性,PHP生态也有成熟的开发库可以直接用。
本地校验令牌的实现逻辑
不需要每次远程调用IdP校验有两种主流落地方案,都不需要每次请求实时和IdP交互:
- 采用带非对称签名的自包含JWT格式访问令牌(最推荐方案)
- 令牌签发阶段:IdP用自己持有的私钥对JWT内容(包含用户标识、权限范围、有效期、签发方、受众等信息)做签名,SPA拿到的JWT本身就携带了所有鉴权需要的信息
- 资源服务器校验阶段:只需要提前持有IdP对应的公钥(公钥可提前配置到资源服务器,也可按天/按周定期从IdP拉取,不需要每次请求同步),本地完成以下校验即可:
- 校验JWT的签名合法性,确认令牌未被篡改、确实是信任的IdP签发
- 校验令牌有效期,确认令牌未过期
- 校验令牌的受众字段,确认令牌是签发给当前资源服务器使用的
- 校验令牌的权限范围,确认令牌持有访问当前接口的对应权限
- 整个校验流程完全在资源服务器本地完成,没有任何远程调用开销。如果需要处理令牌吊销场景,可以通过给访问令牌设置较短有效期+配合刷新令牌续期的方案实现,也可以定期同步IdP的吊销令牌列表到本地缓存,不需要每次请求实时查询IdP。
- 共享存储校验不透明令牌
如果你不想切换成JWT格式令牌,也可以让IdP和资源服务器共享Redis等缓存存储:IdP签发随机字符串格式的不透明令牌时,将令牌对应的元信息存入共享Redis,资源服务器直接查Redis即可完成校验,同样不需要每次调用IdP接口,只是这种方案需要维护跨服务的共享存储依赖,灵活性比JWT方案稍差。
PHP生态可用的相关开发库
- 你当前使用的OAuth2服务端实现本身就原生支持JWT格式访问令牌签发,只需要修改对应配置切换令牌签发模式即可,不需要更换IdP侧的底层实现
- 通用JWT校验可以使用
firebase/php-jwt,这是PHP生态下载量最高、最稳定的JWT处理库,传入公钥和校验规则即可完成全流程验签,代码量极少 - 如果你基于Symfony框架开发,可以直接使用
lexik/jwt-authentication-bundle,该bundle已经封装好了请求拦截、令牌验签、异常处理等全套逻辑,配置好公钥和校验规则后即可自动完成接口的令牌校验,和现有Symfony技术栈适配度很高。
内容的提问来源于stack exchange,提问作者Conde
相关产品推荐
相关产品推荐

