获取被禁止的资源,即使请求的用户是admin



中间件用于保护解析器。中间件检查用户的角色,尽管请求的用户的角色是正确的,但我无法访问listUser查询。我得到以下响应

"errors": [
{
"message": "Forbidden resource",
"extensions": {
"code": "FORBIDDEN",
"response": {
"statusCode": 403,
"message": "Forbidden resource",
"error": "Forbidden"
}
}
}
],
"data": null
}

我的代码

model User {
id            String           @id @default(uuid())
firstName     String
lastName      String
email         String           @unique
username      String           @unique
password      String
confirm       Boolean          @default(false)
isValid       Boolean          @default(false) @map("is_valid")
isSuperuser   Boolean          @default(false)
userRoles     UserRole[]
@@unique([id, email])
}
model Role {
id        String      @id @default(uuid())
name      String      @unique
createdAt DateTime?   @db.Timestamp()
updatedAt DateTime?   @updatedAt @db.Timestamp()
userRoles UserRole[]
}
model UserRole {
id        String    @id @default(uuid())
userId    String
user      User      @relation(fields: [userId], references: [id])
roleId    String
role      Role      @relation(fields: [roleId], references: [id])
createdAt DateTime? @default(now())
updatedAt DateTime? @updatedAt @db.Timestamp()
}
@Injectable()
export class UserMiddleware implements NestMiddleware {
constructor(
private readonly prismaService: PrismaService,
private readonly validationService: ValidationService,
) {}
async use(req: any, res: any, next: () => void) {
if (req.headers.authorization) {
const { userId } = jwt.decode(
String(req.headers.authorization).split(/ /g)[1],
) as JWT;
const user = await this.prismaService.user.findFirst({
where: { id: userId },
include: { userRoles: true },
});
if (user && !user.confirm)
throw new ForbiddenException('User not confirmed');
if (user) {
delete user.password;
req.user = user;
req.user.isAdmin = await this.validationService.isAdmin(userId);
}
}
next();
}
}
@Injectable()
export class ValidationService {
constructor(private readonly prisma: PrismaService) {}
async isAdmin(userId: string): Promise<boolean> {
const u = await this.prisma.role.findUnique({
where: { name: Role.Admin },
});
return await this.prisma.userRole
.count({
// could not find a way to access directly through role name instead of id
where: { userId, roleId: u.id },
})
.then((count) => {
return count ? true : false;
});
}
}
@Query(() => UserPaginated)
@Roles(Role.Admin)
async listUsers(
@Args('paginate', { nullable: true, defaultValue: { skip: 0, take: 50 } })
paginate: PaginationArgs,
@Args('order', {
nullable: true,
defaultValue: { orderBy: 'username', direction: 'desc' },
})
order: OrderListUsers,
@Args('filter', { nullable: true })
filter: FilterListUsers,
) {
return await this.userService.list(paginate, order, filter);
}

为什么我不能以Admin的角色访问listUser?

我认为你的ValidationService有一些问题。请试试这个。但我应该说,这不是完美的解决方案。你的表结构和prisma请求需要一些改进。

@Injectable()
export class ValidationService {
constructor(private readonly prisma: PrismaService) {}
async isAdmin(userId: string): Promise<boolean> {
const u = await this.prisma.role.findUnique({
where: { name: Role.Admin },
});
const userRoleCount = await this.prisma.userRole
.count({
where: { userId, roleId: u.id },
});
return userRoleCount > 0;
}
}

最新更新