Nest-Keycloak-connect中@Public()装饰器失效,查询公共房屋接口未授权
Nest-Keycloak-connect @Public()装饰器在自动生成的Resolver上不生效的解决方案
问题背景
使用nest-keycloak-connect时,通过nestjs-query-graphql自动生成的Housing查询接口,即使在DTO上添加了@Public()装饰器,未登录用户仍会收到Unauthorized错误。登录状态下功能正常,需要实现未登录时可查询房屋数据。
原因分析
@Public()装饰器需要应用在Resolver类或其方法上,而非DTO。nest-keycloak-connect的AuthGuard、ResourceGuard是基于控制器/Resolver的元数据进行权限校验的,DTO作为数据传输对象,其装饰器不会被守卫识别。nestjs-query自动生成的Resolver默认没有公共权限标记,因此会被拦截。
解决方案
方案一:为自动生成的Resolver添加类级@Public()装饰器
修改HousingModule中NestjsQueryGraphQLModule的配置,通过decorators选项将@Public()应用到生成的Resolver类上:
import { Module } from "@nestjs/common"; import { NestjsQueryGraphQLModule } from "@ptc-org/nestjs-query-graphql"; import { NestjsQueryTypeOrmModule } from "@ptc-org/nestjs-query-typeorm"; import { HousingDTO } from "./housing.dto"; import { HousingEntity } from "./housing.entity"; import { HousingInputDTO } from "./housing.input.dto"; import { Public } from "nest-keycloak-connect"; @Module({ imports: [ NestjsQueryGraphQLModule.forFeature({ imports: [NestjsQueryTypeOrmModule.forFeature([HousingEntity])], resolvers: [{ DTOClass: HousingDTO, EntityClass: HousingEntity, CreateDTOClass: HousingInputDTO, // 为生成的Resolver类添加@Public()装饰器 decorators: [Public()] }] }) ], }) export class HousingModule {}
方案二:仅为特定查询方法添加@Public()
如果需要保留创建/更新/删除接口的权限校验,只开放查询方法,可以使用methodDecorators配置:
resolvers: [{ DTOClass: HousingDTO, EntityClass: HousingEntity, CreateDTOClass: HousingInputDTO, // 只为findOne、findMany等查询方法添加公共权限 methodDecorators: { findOne: [Public()], findMany: [Public()] } }]
额外检查
确保AppModule中的PolicyEnforcementMode设置为PERMISSIVE(你已正确配置),该模式下未明确配置权限的资源不会被强制拦截,但自动生成的Resolver仍需通过@Public()标记来跳过AuthGuard校验。
内容的提问来源于stack exchange,提问作者Mehmet Yazkan
相关产品推荐
相关产品推荐

