Nest.js集成AWS Cognito后如何获取当前用户属性
Nest.js + AWS Cognito 路由获取当前用户属性最优实现
核心逻辑是利用Passport JWT策略的校验结果挂载机制,分两种实现方案按需选择:
方案1:直接从JWT Payload提取(性能最优,无额外请求)
这种方案无需额外调用Cognito接口,只需调整现有代码即可,要求你已在AWS Cognito控制台配置将邮箱、手机号等需要的属性映射到ID令牌的自定义声明中。
步骤1:修改JwtStrategy的validate方法
现有validate方法仅返回布尔值,Passport会将validate方法的返回值自动挂载到请求对象的user属性上,直接返回payload即可获取所有令牌内的属性:
// jwt.strategy.ts public async validate(payload: any) { // 可在这里按需过滤payload字段,只返回需要的用户属性 return { userId: payload.sub, email: payload.email, phoneNumber: payload.phone_number, username: payload['cognito:username'] }; }
注意:要获取用户属性需要前端请求时在Authorization头传Cognito返回的ID令牌,而非访问令牌,默认访问令牌不会携带用户自定义属性
步骤2:创建自定义用户参数装饰器(可选但推荐)
避免每次手动从请求对象取user,封装专用装饰器:
// src/common/decorators/current-user.decorator.ts import { createParamDecorator, ExecutionContext } from '@nestjs/common'; export const CurrentUser = createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.user; }, );
步骤3:路由中直接获取用户属性
// app.controller.ts import { Controller, Get, UseGuards, Header } from '@nestjs/common'; import { AppService } from './app.service'; import { AuthGuard } from '@nestjs/passport'; import { CurrentUser } from './common/decorators/current-user.decorator'; @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() @UseGuards(AuthGuard('jwt')) @Header('Content-Type', 'text/html') getHello(@CurrentUser() user: any): string { // 直接使用user对象里的属性 console.log('当前用户邮箱:', user.email); console.log('当前用户手机号:', user.phoneNumber); return this.appService.getHello(); } }
方案2:调用Cognito接口实时查询(数据最新,适用于属性经常变更场景)
如果需要获取未映射到令牌的属性,或者需要保证属性是最新状态,可以调用Cognito的getUser接口查询:
步骤1:在AuthService中新增获取用户属性方法
// auth.service.ts // 新增方法 getUserAttributes(accessToken: string): Promise<Record<string, any>> { return new Promise((resolve, reject) => { const cognitoUser = new CognitoUser({ Username: '', // 可留空,Cognito会从accessToken解析用户 Pool: this.userPool, }); cognitoUser.setSignInUserSession({ getAccessToken: () => ({ getJwtToken: () => accessToken }), getIdToken: () => ({ getJwtToken: () => accessToken }), getRefreshToken: () => ({ getToken: () => '' }), isValid: () => true, }); cognitoUser.getUserAttributes((err, attributes) => { if (err) return reject(err); const userAttrs = {}; attributes.forEach(attr => userAttrs[attr.getName()] = attr.getValue()); resolve(userAttrs); }); }); }
步骤2:在JwtStrategy中调用方法补全用户属性
// jwt.strategy.ts public async validate(payload: any, request: Request) { const token = ExtractJwt.fromAuthHeaderAsBearerToken()(request); // 调用Cognito接口获取最新属性 const userAttrs = await this.authService.getUserAttributes(token); return { userId: payload.sub, ...userAttrs }; }
后续路由获取用户属性的方式和方案1一致即可。
内容的提问来源于stack exchange,提问作者Detoner
相关产品推荐
相关产品推荐

