ZVE*_*R3D 3 node.js typescript passport.js nestjs nestjs-passport
我使用带有 jwt 策略的带护照的 Nestjs。我想根据我的一些请求获得当前用户。目前,我有一个看起来像这样的装饰器:
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const user = ctx.switchToHttp().getRequest().user;
if (!user) {
return null;
}
return data ? user[data] : user; // extract a specific property only if specified or get a user object
},
);
Run Code Online (Sandbox Code Playgroud)
当我在带有 AuthGuard 的路线上使用它时,它按预期工作:
@Get('test')
@UseGuards(AuthGuard())
testRoute(@CurrentUser() user: User) {
console.log('Current User: ', user);
return { user };
}
Run Code Online (Sandbox Code Playgroud)
但是我如何让它在非保护路线上工作(获取当前用户)?我需要用户无论是否获得授权都能够发表他们的评论,但是,当他们登录时,我需要得到他们的名字。
基本上,我需要一种方法来在每个(或至少在一些不是 AuthGuard 的请求上)传播 req.user,通过应用护照中间件在 express 中做真的很简单,但我不知道该怎么做它与@nestjs/passport。
[编辑] 感谢 vpdiongzon 为我指明了正确的方向,我选择根据他的回答制作一个守卫,这只是用 user 或 null 填充 req.user :
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class ApplyUser extends AuthGuard('jwt') {
handleRequest(err: any, user: any) {
if (user) return user;
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以在需要获取当前用户的任何未受保护的路线上使用它
@Get('me')
@UseGuards(ApplyUser)
me(@CurrentUser() user: User) {
return { user };
}
Run Code Online (Sandbox Code Playgroud)
小智 6
无论如何,您都需要将 AuthGuard 应用于每条路线,但如果您有一条不需要身份验证的路线,只需添加一个自定义装饰器,例如:
Auth Guard
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private readonly reflector: Reflector) {
super();
}
handleRequest(err, user, info, context) {
const request = context.switchToHttp().getRequest();
const allowAny = this.reflector.get<string[]>('allow-any', context.getHandler());
if (user) return user;
if (allowAny) return true;
throw new UnauthorizedException();
}
}
Run Code Online (Sandbox Code Playgroud)
全局应用 app.module.js 中的 AuthGuard
import { APP_GUARD, Reflector } from '@nestjs/core';
import { AppController } from './app.controller';
import { JwtAuthGuard } from './app.guard';
@Module({
imports: ],
controllers: [AppController],
providers: [
{
provide: APP_GUARD,
useFactory: ref => new JwtAuthGuard(ref),
inject: [Reflector],
},
AppService,
],
})
export class AppModule {
}
Run Code Online (Sandbox Code Playgroud)
允许无需身份验证的路由的自定义装饰器
import { SetMetadata } from '@nestjs/common';
export const AllowAny = () => SetMetadata('allow-any', true);
Run Code Online (Sandbox Code Playgroud)
在路由中应用 AllowAny,如果 AllowAny 装饰器没有附加在控制器路由中,它将需要一个用户。
@Post('testPost')
@AllowAny()
async testPost(@Req() request) {
console.log(request.user)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3406 次 |
最近记录: |