如果文件相关的内容的发布状态不是 published,普通用户就不能通过文件服务接口还有文件元数据接口获取到这个文件相关的数据。下面我们可以定义一个守卫去检查一下用户是否可以使用文件服务还有文件元数据接口。
在终端,项目所在目录的下面,执行 nest generate guard 生成一个守卫,名字是 file-access,放在 file/guards 里面,加上一个 --flat 选项。
回到项目,打开 FileAccessGuard 这个守卫,在这个类里面添加一个构造方法,然后注入两个依赖,需要一个 appAbilityFactory,类型是 AppAbilityFactory,再注入一个 Repository,实体类型是 FileEntity,名字是 fileRepository,导入需要的这些东西。
在 async 标记一下 canActivate ,返回的值的类型是 Promise
下面可以创建用户能力,声明一个 userAbility,等于 this.appAbilityFactory.createAbilityForUser,把 user 交给它。
然后声明一个 file ,等于 await,用一下 this.fileRepository.findOne,提供一个 fileId,一个选项参数,添加一个 relations,需要 post 这个关系。
最后 return 的东西,可以用一下 userAbility.can 检查用户是否能做些什么,动作是 Action.read ,主题是 file.post 。
使用守卫
打开 file-metadata.controller,在这个文件元数据接口上面,使用一个守卫,添加一个 FileAccessGuard。再打开 file-serve.controller,在这个文件服务接口上面,也使用一个守卫,用一个 FileAccessGuard。
测试
在 Http 客户端可以测试一下,打开文件元数据接口,发送一下请求,可以正常得到响应。在数据库客户端,观察一下 id 号是 2 的这个文件相关的内容的 id ,在 post 数据表里找到这个内容,手工把它的状态改成 draft ,保存一下。
回到 Http 客户端,发送一下这个文件元数据请求,这回得到的响应,状态码会是 403 ,因为跟这个要访问的文件相关的内容,它的发布状态不是 published,所以普通用户就没有权限获取到这个文件的元数据。
这个内容的作者是李白,复制一下李白的令牌,回到文件元数据请求,配置一下身份验证,类型是 Bearer Token ,把令牌粘贴到 Token 字段这里。再发送一下这个请求。这次可以正常得到响应,虽然内容的发布状态不是 published,但是内容作者对内容来说可以执行 mange 动作,所以可以正常得到这个文件的元数据。
再试一下文件服务,发送请求,响应的状态码是 403,表示没有权限,配置一下身份验证,类型是 Bearer Token ,把令牌粘贴到这里,再发送一下这个请求,这回就正常得到了这个响应的图像文件。