我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?
Posted
技术标签:
【中文标题】我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?【英文标题】:I'm using a passport-jwt auth strategy in my nestJS app (with authGuard), how to get access to the token payload in my controller? 【发布时间】:2019-08-29 09:37:34 【问题描述】:我正在尝试访问受 AuthGuard
保护的路由中的 jwt 有效负载。
我正在使用passport-jwt
,令牌有效负载是用户的电子邮件。
我可以通过运行下面的代码来实现:
import
Controller,
Headers,
Post,
UseGuards,
from '@nestjs/common';
import JwtService from '@nestjs/jwt';
import AuthGuard from '@nestjs/passport';
@Post()
@UseGuards(AuthGuard())
async create(@Headers() headers: any)
Logger.log(this.jwtService.decode(headers.authorization.split(' ')[1]));
我想知道是否有更好的方法?
【问题讨论】:
旁注:创建Logger
的实例比静态使用它更好。看到这个答案:***.com/a/52907695/4694994
【参考方案1】:
您的JwtStrategy
有一个validate
方法。在这里您可以访问JwtPayload
。此方法的返回值将附加到请求中(默认在属性user
下)。所以你可以在这里从有效载荷中返回你需要的任何东西:
async validate(payload: JwtPayload)
// You can fetch additional information if needed
const user = await this.userService.findUser(payload);
if (!user)
throw new UnauthorizedException();
return user, email: payload.email;
然后通过注入请求在你的控制器中访问它:
@Post()
@UseGuards(AuthGuard())
async create(@Req() request)
Logger.log(req.user.email);
您可以通过创建自定义装饰器使这更方便:
import createParamDecorator from '@nestjs/common';
export const User = createParamDecorator((data, req) =>
return req.user;
);
然后注入@User
而不是@Req
。
【讨论】:
我认为您不需要在validate
函数中调用 validateUser(payload)
。此时您的有效载荷已经有效,并由Passport
解码。您应该简单地返回新对象return user, email: payload.email;
就像在文档中一样:“一个“验证回调”,你告诉 Passport 如何与你的用户存储(你管理用户帐户的地方)交互。在这里,你验证一个用户存在(和/或创建新用户),以及他们的凭据是否有效。如果验证成功,Passport 库希望此回调返回完整用户,如果失败则返回 null(失败定义为用户是未找到,或者在本地护照的情况下,密码不匹配)。” docs.nestjs.com/techniques/authentication
对于其他策略,是的,但对于 JWT,它不是必需的,因为您的令牌已经过签名和验证。请参阅该文档的后面部分,了解为什么您不必在此处再次验证用户。
是的,这是正确的,您不需要再次验证令牌本身。但是,您可能希望使用该挂钩来获取附加数据以将其附加到请求中。或者,如果您有一个长期存在的令牌(在大多数情况下可能不推荐使用),您可能需要检查用户是否仍然存在、是否被列入黑名单等。我已经编辑了答案以包含您的观点。
参数装饰器应该使用执行上下文来实现:import createParamDecorator, ExecutionContext from '@nestjs/common'; export const User = createParamDecorator( (data: any, ctx: ExecutionContext) => const request = ctx.switchToHttp().getRequest(); return request.user; , )
以上是关于我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?的主要内容,如果未能解决你的问题,请参考以下文章