基于OAuth2规范,Next.js+oidc-client如何安全获取用户权限?
OAuth2 PKCE模式下UI端获取用户权限的最佳方案
问题背景
我正在开发一个采用OAuth2 PKCE的认证项目,认证服务器为Microsoft Identity Server搭配OpenIddict。用户登录后,服务器会返回ID Token和Access Token,用户权限以Claims形式包含在Access Token中。我的UI基于Next.js构建,使用oidc-client库,需根据用户权限启用或禁用特定功能。
目前已完成以下步骤:
- 基于Microsoft Identity Server和OpenIddict实现OAuth2 PKCE用户认证;
- 配置认证服务器将用户权限作为Claims放入Access Token中。
但遇到的问题是:直接在UI中解析Access Token存在安全风险,且OpenIddict默认加密Access Token payload导致无法在UI中读取(虽然可以禁用加密,但不推荐)。想知道依据OAuth2.0规范,在UI中获取用户权限的最佳方式是什么?
合规解决方案
根据OAuth2.0和OpenID Connect规范,针对Next.js + oidc-client的场景,推荐以下几种优先级从高到低的方案:
1. 将权限Claims放入ID Token(首推)
ID Token的核心设计目标就是供客户端(UI)解析使用,它本身是签名但不加密的(除非客户端主动要求加密),完全符合OpenID Connect的标准用法。
- 在OpenIddict中,可通过配置
AddIdentityClaims或自定义Claims提供器,将用户权限相关的Claims添加到ID Token的Claims集合中; - oidc-client库会自动完成ID Token的解析与验证,你可以直接通过
user.profile对象获取权限信息,无需手动解析Token,既安全又合规。
2. 通过UserInfo端点获取权限
如果权限信息条目较多,不适合放入ID Token(避免Token体积过大影响性能),可以借助OpenID Connect标准的UserInfo端点获取完整权限:
- 用户登录成功后,oidc-client会自动持有有效的Access Token,你可以调用库内置的
user.getUserInfo()方法,向认证服务器的UserInfo端点发起请求; - 认证服务器验证Access Token有效性后,会返回包含用户权限Claims的响应;
- 这种方式完全符合规范,既规避了UI端解析Access Token的风险,又能获取更全面的用户权限数据。
3. 禁用Access Token加密(不推荐)
虽然可以通过配置关闭OpenIddict的Access Token payload加密,但这属于违背安全最佳实践的操作:
- Access Token的设计初衷是供后端API服务验证使用,客户端(UI)不应依赖解析它;
- 禁用加密后,Access Token的payload会以明文形式存在(仅保留签名),一旦Token被拦截,攻击者可直接读取权限信息,大幅提升安全风险。
内容的提问来源于stack exchange,提问作者yasith rangana
相关产品推荐
相关产品推荐

