求助:如何在TypeScript中解码AWS Hosted UI返回的Cognito JWT获取用户ID
在TypeScript中解码AWS Cognito JWT并获取UserID的实现方案
一、核心信息说明
AWS Cognito返回的idToken里,sub字段就是你需要的UserID(可作为DynamoDB分区键)。解码分两种场景:开发环境快速调试用(不验证签名),生产环境必须做签名合法性验证。
二、开发环境快速解码(仅用于调试)
JWT由.分割为三部分,中间的Payload是Base64URL编码的JSON,直接解码就能拿到sub:
function decodeCognitoIdToken(token: string): { sub: string } | null { try { const parts = token.split('.'); if (parts.length !== 3) throw new Error('Invalid JWT format'); // 转换Base64URL为标准Base64编码 const payloadBase64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); // 补全Base64的填充字符 const paddedPayload = payloadBase64.padEnd(payloadBase64.length + ((4 - payloadBase64.length % 4) % 4), '='); const decodedPayload = atob(paddedPayload); return JSON.parse(decodedPayload) as { sub: string }; } catch (err) { console.error('Failed to decode token:', err); return null; } } // 使用示例 const idToken = '你的Cognito返回的idToken'; const userData = decodeCognitoIdToken(idToken); if (userData) { const userId = userData.sub; console.log('User ID:', userId); // 后续用userId查询DynamoDB }
三、生产环境安全解码(必须验证签名)
直接解码存在伪造风险,必须验证JWT的签名、过期时间、受众等信息,推荐用AWS官方维护的aws-jwt-verify库:
- 安装依赖:
npm install aws-jwt-verify
- 验证并解码的代码:
import { CognitoJwtVerifier } from 'aws-jwt-verify'; // 初始化验证器,配置你的Cognito信息 const verifier = CognitoJwtVerifier.create({ userPoolId: '你的用户池ID(例:us-east-1_xxxxxx)', tokenUse: 'id', // 指定验证idToken,而非accessToken clientId: '你的Cognito客户端ID', }); async function verifyAndDecodeIdToken(token: string): Promise<string | null> { try { const payload = await verifier.verify(token); // 验证通过后,payload.sub即为UserID return payload.sub; } catch (err) { console.error('Token verification failed:', err); return null; } } // 结合DynamoDB读取数据的示例(使用AWS SDK v3) async function fetchAndRenderUserData(idToken: string) { const userId = await verifyAndDecodeIdToken(idToken); if (!userId) return; import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb'; import { unmarshall } from '@aws-sdk/util-dynamodb'; const client = new DynamoDBClient({ region: '你的AWS区域' }); const command = new GetItemCommand({ TableName: '你的DynamoDB表名', Key: { userId: { S: userId } // 假设分区键为字符串类型的userId } }); try { const response = await client.send(command); if (response.Item) { const userData = unmarshall(response.Item); // 在这里渲染用户数据到页面 console.log('Fetched user data:', userData); } else { console.log('No user data found'); } } catch (dbErr) { console.error('DynamoDB fetch failed:', dbErr); } }
关键注意事项
- 生产环境绝对不能使用无验证的解码,否则可能被恶意用户伪造身份窃取数据。
- 必须设置
tokenUse: 'id',因为accessToken不包含用户身份核心信息,不能用来获取UserID。 - AWS SDK v3需要单独安装对应包,比如
@aws-sdk/client-dynamodb和@aws-sdk/util-dynamodb。
内容的提问来源于stack exchange,提问作者Om Patel
相关产品推荐
相关产品推荐

