用户登录

先去定义一个 enum,在 src,core,enums 里面添加一个文件,名字是 possession.enum.ts,文件里面 export 一个 enum 名字叫 Possession,里面添加一个 OWN,对应的值是 own ,在设置权限 的时候会用到这个 enum。

再打开我们在项目里添加的 Permission 接口, 在这个接口里再添加两个属性,一个是 resource,类型是 string,还有一个 possession,类型是 Possession 这个 enum。

现在使用 Permissions 装饰器设置权限的时候,每一条权限里面都可以包含 resource,possession 还有 role。

打开 PostController,找到更新内容用的路由。

在这条路由上我需要检查用户的权限, @UseGuards ,先用一下 AuthGuard(),需要用户先通过身份验证,接着再用一个 AccessGuard, 用它检查用户的权限 。

然后使用一个 @Permissions 装饰器设置一下需要的检查的权限,添加一条权限 ,用 resource 先设置一下这个资源的名字。

这个资源名字也可以使用一个 enum ,在项目里再去创建一个 enum,添加一个文件,名字是 resource.enum.ts。

文件里导出一个 enum,Resource,里面添加一个 POST,对应的值是 posts,再添加一个 COMMENT,对应的值是 comments。

回到 UserController,设置权限的时候,resource 的值可以是 Resource.POST ,表示 posts 资源,这个 posts 应该是在 user 实体上定义的一个关系 , 再添加一个 possession 它的值是 Possession.OWN 。

这条权限的意思就是,用户需要拥有这个 post 资源,才能让他编辑这个内容。

AccessGuard

打开 AccessGuard,在这个守卫的 canActivate 方法里,使用 validatePermissions 的时候再提供一个资源的 id 参数,用 parseInt 处理 request.params.id ,表示的是请求地址里的 id 参数。

然后找到 validatePermissions 方法的定义,让它接收一个新的参数,名字是 resourceId,类型是 number。

map permissions 的时候,从 permission 里面把 resource,还有 possession 解构出来。

添加一个 hasPossession,类型是 boolean。

判断一下,如果 possession 的值等于 Possession.OWN,就是等于字符串 own,设置 hasPossession 的值,它的值就是 user 服务上的 possess 方法返回的结果 。

在这个类里面,把 User 服务注入进来,在构造方法里添加一个属性,private readonly userService,类型是 UserService。

hasPossession 的值是 await 用一下 this.userService 上的 possess,它需要 user.id,resource,还有 resourceId,.

这个方法 return 的是 hasRole,&& hasPossession, 在上面定义 hasPossession 还有 hasRole 的时候,让它们默认的值等于 true。

测试

下面再去试一下这个检查权限的功能,打开数据库客户端,在 post 表里面,找一个要编辑的内容,比如 id 号是 15 的这个内容,复制一下这个内容的标题,这个内容的作者的 id 号是 6,对应的用户是李白。

回到 Http 客户端,打开 Post Update 请求,请求地址是 posts/15,设置一下要更新的内容,添加一个 title,设置一下要修改的标题内容,结尾加上一个 ! 号。

现在要更新内容需要验证用户的身份,先得去登录一下。

打开 Auth Login,暂时先用王皓这个用户的身份登录,复制一下请求回来的 token。

打开 Post Update 请求,设置一下身份验证,把 token 值粘贴到这里,发送一下这个请求,得到了一个 403 的响应,说明发出这个请求的用户没有权限。

因为这个路由上设置了一条权限,要求请求的用户必须拥有这个指定的资源。

再打开 Auth Login,这回可以使用李白的身份申请一下登录,复制请求回来的 token 值。

粘贴到 Post Update 请求的身份验证这里,再发送一下这个请求,这回就会得到了一个成功更新内容的响应,因为发起这个请求的用户,拥有这个指定的内容资源..

再试一下,打开 PostController,找到 update 方法,设置的这条权限里面,给它再加上一个 role,要求的用户角色是 UserRole.VIP 。

回到 HTTP 客户端,发送一下这个请求。

又得到了一个没有权限的响应,虽然发出这个请求的用户拥有这个资源,但是他的用户角色里面并没有 VIP 这个角色。

在数据库客户端,我们先手工给这个用户分配一个用户角色,打开 user_roles_role 这个数据表,添加一条记录,userId 是 6,roleId 是 2,这个就是 VIP 这个角色在 role 这个表里的 id 号。

回到 Http 客户端,重新再发送一下这个请求,这回就又可以得到成功更新了内容资源的响应,因为当前发出这个请求的用户,拥有这个指定的内容资源,同时他也拥有 VIP 这个用户角色。

用权限控制守卫检查用户是否拥有指定资源《 Nest.js 应用框架:权限控制 》

统计

14696
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点