gpt4 book ai didi

javascript - 如何在Plumier中创建基于用户权限的可重用自定义授权

转载 作者:行者123 更新时间:2023-11-30 19:10:58 25 4
gpt4 key购买 nike

我在创建可重复用于多个 Controller 的自定义授权时遇到问题。来自示例 here看起来自定义授权不能重用到另一个具有不同签名的 Controller 中。

在我的例子中,我有一些具有某些 Angular 色授权的端点,以防止未经授权的用户访问某些端点。

RoomsUsersController
POST /rooms/:roomId/users/:userId/kick -> role: RoomAdmin
POST /rooms/:roomId/users/:userId/promote -> role: RoomAdmin
GET /rooms/:roomId/users?offset&limit -> role: RoomAdmin, RoomUser

只有 RoomAdmin 可以踢出和提升用户,并且只有注册的 RoomUserRoomAdmin 才能看到房间的用户列表。

我还创建了另一个由另一个 Controller 处理的速记端点,通过在帖子正文中提供 roomId 来踢和提升用户,如下所示。


UsersController
POST /users/:id/kick body: {roomId} -> role: RoomAdmin
POST /users/:id/promote body: {roomId} -> role: RoomAdmin

RoomsUsersControllerUsersController 的签名如下所示(方法主体和验证已删除)

@route.root("/rooms/:roomId/users")
export class RoomsUsersController {

@route.post(":userId/kick")
kick(roomId:string, userId:string){}

@route.post(":userId/promote")
promote(roomId:string, userId:string){}
}

export class UsersController {

@route.post(":id/kick")
kick(id: string, @bind.body() body: { roomId: string }) { }

@route.post(":id/promote")
promote(id: string, @bind.body() body: { roomId: string }) { }
}

我目前的解决方案是为 RoomsUsersControllerUsersController 创建不同的自定义授权,但它不那么干而且看起来很麻烦。

//custom authorization for RoomsUsersController
function roomUser(...roles: string[]) {
return authorize.custom(async ({ user, parameters }) => {
const room = await RoomModel.findById(parameters[0]).populate("users")
const roomUser = room.users.find(x => x.userId === user.userId)
if(!roomUser) throw new HttpStatusError(401, "Unauthorized user")
return roles.some(x => x === roomUser.role)
})
}

parameter[0] 不适用于 UsersController,因为它具有不同的签名。有人遇到同样的问题吗?

最佳答案

这是您需要的 route 属性。它包含有关当前 Controller/Action 处理请求的元数据信息。您可以使用 route.action.parameters 等获取当前操作参数元数据列表,其中包含参数名称、参数类型等,您可以查看完整架构 here .

您的 Controller 的问题是它们之间没有相似之处,无法检索自定义授权将使用的 roomId。您可以像下面这样修改您的 UsersController:

export class UsersController {

@route.post(":id/kick")
kick(id: string, roomId: string) { }

@route.post(":id/promote")
promote(id: string, roomId: string) { }
}

请注意,您可以将请求正文属性分解为多个参数。上面的代码显示之前的body: { roomId: string } 参数可以简化为roomId:string。如果 body 参数有更多属性,您可以简单地将它们分解为具有适当名称和类型的参数。

现在使用上面的 Controller ,UsersControllerRoomsUsersController 之间有相似之处,即 roomId 参数。您现在可以使用 route.action.parameters 访问它们,现在完整的自定义授权如下所示:

function roomUser(...roles: string[]) {
return authorize.custom(async ({ user, route, parameters }) => {
const index = route.action.parameters.findIndex(x => x.name === "roomId")
if(index === -1)
throw new Error(`No parameter roomId found in
{route.controller.name}.${route.action.name}`)
const room = await RoomModel.findById(parameters[index]).populate("users")
const roomUser = room.users.find(x => x.userId === user.userId)
if(!roomUser) throw new HttpStatusError(401, "Unauthorized user")
return roles.some(x => x === roomUser.role)
})
}

上面代码的想法是:你在 Action 参数中找到名为roomId的参数的位置,而不是从带有索引的parameters中获取值。

关于javascript - 如何在Plumier中创建基于用户权限的可重用自定义授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58481395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com