nestjs 中的可选身份验证
Posted
技术标签:
【中文标题】nestjs 中的可选身份验证【英文标题】:Optional Authentication in nestjs 【发布时间】:2019-04-14 10:39:48 【问题描述】:我想知道是否存在使req.user
对象在控制器方法中可用的装饰器,如果用户已登录(发送了授权标头),如果没有,则让req.user
为空。
如果用户未登录,AuthGuard
装饰器将返回 401,因此不适合我的情况。
【问题讨论】:
如果您还没有,请查看:docs.nestjs.com/techniques/authentication 【参考方案1】:没有内置的装饰器,但您可以轻松地自己创建一个。请参阅docs 中的示例:
import createParamDecorator from '@nestjs/common';
import AuthGuard from '@nestjs/passport';
export const User = createParamDecorator((data, req) =>
return req.user;
);
由于内置的AuthGuard
抛出异常,你可以创建自己的版本并覆盖请求处理程序:
@Injectable()
export class MyAuthGuard extends AuthGuard('jwt')
handleRequest(err, user, info)
// no error is thrown if no user is found
// You can use info for logging (e.g. token is expired etc.)
// e.g.: if (info instanceof TokenExpiredError) ...
return user;
确保您没有在JwtStrategy
中抛出错误:
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy)
constructor(private readonly authService: AuthService)
super(
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'secretKey',
);
async validate(payload)
const user = await this.authService.validateUser(payload);
// in the docs an error is thrown if no user is found
return user;
然后你可以像这样在Controller
中使用它:
@Get()
@UseGuards(MyAuthGuard)
getUser(@User() user)
return user;
【讨论】:
完美答案。在***和github上找不到它。 我找不到@User 装饰器 @jeromerg 这是一个自定义装饰器,在此答案的第一个代码 sn-p 中定义。【参考方案2】:另一种方法是创建匿名护照策略:
// In anonymous.strategy.ts
@Injectable()
export class AnonymousStrategy extends PassportStrategy(Strategy, 'anonymous')
constructor()
super()
authenticate()
return this.success()
然后,在控制器中链接这个策略:
// In create-post.controller.ts
@Controller()
export class CreatePostController
@UseGuards(AuthGuard(['jwt', 'anonymous'])) // first success wins
@Post('/posts')
async createPost(@Req() req: Request, @Body() dto: CreatePostDto)
const user = req.user as ExpressUser
if (user.email)
// Do something if user is authenticated
else
// Do something if user is not authenticated
...
【讨论】:
谢谢,我觉得用这个比较灵活。因为有时我们需要拒绝未经身份验证的用户。 我用我的 Graphql Guard ``` import Injectable, ExecutionContext from '@nestjs/common' import AuthGuard from '@nestjs/passport' import GqlExecutionContext from '@nestjs /graphql' @Injectable() 导出类 EveryoneGqlAuthGuard 扩展 AuthGuard(['jwt', 'anonymous']) getRequest(context: ExecutionContext) const ctx = GqlExecutionContext.create(context) return ctx.getContext().req ```以上是关于nestjs 中的可选身份验证的主要内容,如果未能解决你的问题,请参考以下文章