Cognito用户池移除用户组权限需重登才生效,如何实现即时禁用?
问题根因
Cognito签发的JWT令牌为自包含凭证,默认有效期最长可达24小时,令牌签发时会静态写入用户所属用户组等声明信息。AppSync内置的@aws_auth指令仅校验JWT的签名有效性和过期时间,不会实时查询Cognito侧用户的最新组状态,因此将用户移出组后,只要旧令牌未过期,用户仍可凭借原有令牌访问受限接口。
可行解决方案
方案1:改用AppSync自定义Lambda授权器(权限实时性最高)
替换原有@aws_auth内置鉴权,用自定义Lambda授权器实现所有请求的权限校验,每次请求都实时拉取用户最新组信息做匹配:
import { CognitoIdentityProviderClient, AdminListGroupsForUserCommand } from "@aws-sdk/client-cognito-identity-provider"; const cognitoClient = new CognitoIdentityProviderClient({ region: process.env.COGNITO_REGION }); // 鉴权逻辑示例 export const authHandler = async (event) => { // 第一步:解析并校验JWT签名合法性 const decodedToken = parseAndVerifyJwt(event.authorizationToken); // 第二步:实时查询Cognito侧用户所属的最新组 const groupResp = await cognitoClient.send(new AdminListGroupsForUserCommand({ UserPoolId: decodedToken.iss.split('/').pop(), Username: decodedToken.sub })); const currentUserGroups = groupResp.Groups.map(item => item.GroupName); // 第三步:匹配接口所需权限,返回放行/拒绝策略 if (currentUserGroups.includes('StandardUsers')) { return generateIamPolicy(decodedToken.sub, 'Allow', event.methodArn); } return generateIamPolicy(decodedToken.sub, 'Deny', event.methodArn); };
方案2:移除用户组时同步全局吊销用户凭证
无需修改现有鉴权逻辑,仅在用户组变更的操作流中增加Cognito令牌吊销步骤:
- 调用Cognito的
AdminUserGlobalSignOut接口,直接失效该用户所有已签发的访问令牌、ID令牌和刷新令牌 - 开启Cognito用户池的令牌撤销功能,吊销后的令牌即使未过期也无法通过AppSync的JWT校验
- Amplify会在后续请求尝试刷新令牌时感知到失效,自动触发用户重新登录
方案3:业务Lambda层二次校验(改造成本最低)
保留原有@aws_auth作为第一层鉴权,在AppSync触发的业务Lambda中新增权限校验逻辑,执行业务代码前先验证用户最新组状态:
import { CognitoIdentityProviderClient, AdminListGroupsForUserCommand } from "@aws-sdk/client-cognito-identity-provider"; const cognitoClient = new CognitoIdentityProviderClient({ region: process.env.COGNITO_REGION }); // 业务逻辑入口示例 export const businessHandler = async (event) => { const cognitoIdentity = event.identity; // 新增实时校验逻辑 const groupResp = await cognitoClient.send(new AdminListGroupsForUserCommand({ UserPoolId: process.env.COGNITO_USER_POOL_ID, Username: cognitoIdentity.sub })); const currentGroups = groupResp.Groups.map(g => g.GroupName); if (!currentGroups.includes('StandardUsers')) { throw new Error('AccessDenied: 无权限执行该操作'); } // 原有业务逻辑 // ... }
客户端补充优化
可在Amplify的请求拦截器中增加定时校验逻辑,每10-15分钟拉取一次当前用户的最新组信息,发现权限变更时主动清除本地令牌并触发登出,进一步降低用户侧感知延迟。
内容的提问来源于stack exchange,提问作者Force Hero
相关产品推荐
相关产品推荐

