概述
在前一个教程中,我们了解了如何通过登录到 Airlock 来验证用户的身份。但是还有更多工作要做!
我们知道 Airlock 有两种不同的用户类型:访客和房东。而每种类型的用户仅允许执行某些任务。(例如,房东可以管理位置清单,而访客不能。)
现在我们已经学习了如何对用户进行身份验证,下一步是授权:检查已登录用户是否被允许执行他们正在尝试执行的任何操作。
在本教程中,我们将
- 学习如何使用
context授予 字段在 解析器级别获得授权用户的访问权限。
🔐 授权
与身份验证一样,有多种方法可以进行授权。首先,有权限级别:你可以限制访问整个 API、单个 数据源或单个 字段。接下来是实现:你可以定义自定义 指令,甚至让 GraphQL 服务器外部的服务来负责授权!(你可以在 Apollo Server 授权文档。)
对于 Airlock,我们使用 字段级授权。这意味着,每个 解析器都会检查已登录用户是否有权访问 图的该部分。
通过探索面向某个特定 突变: createListing,来仔细了解 Airlock 中的授权。
在 createListing 解析器内
如前所述,Airlock 房东可以创建他们想出租给客人的房源列表。当房东想要创建新房源列表时,Airlock 客户端会调用 createListing 突变。
只有 房东可以创建房源列表,所以 createListing 突变需要具有授权保护措施,以防止 客人执行该操作。
面向 createListing 的 解析器位于 server/resolvers.js 文件中。回想一下, 解析器是一个具有四个可选参数的函数: parent、 args、 context和 info。第三个参数 context,就是我们在上一课中设置的 userId和 userRole属性所在的位置。
在 resolvers.js 文件中搜索 createListing mutation。它看起来像这样:
createListing: async (_, { listing }, { dataSources, userId, userRole }) => {// the user needs to be logged in to create a listingif (!userId) throw AuthenticationError();if (userRole === "Host") {// hosts can create listings} else {// throw a ForbiddenError}};
首先,resolver 检查是否存在 context 对象中的 userId,因为用户必须登录才能创建清单。如果不存在已登录的用户,则 resolver 抛出 AuthenticationError。
接下来,resolver 检查 userRole 是否为 Host,然后再执行创建清单的逻辑。如果用户不是主持人,则 resolver 返回一个错误。
注意: AuthenticationError 和 ForbiddenError 是在 utils/errors.js 文件中定义的错误。有关如何创建自定义错误和代码的更多信息,请查看 Apollo 错误处理文档。
您可以在其他 resolvers 中使用类似的结构,以确保只有具有特定角色的用户才能访问某些 fields 或 operations。想要更多示例?查看 upcomingGuestBookings 或 updateProfile 的 resolvers。
实践
重点要点
- 使用 字段- 级别授权,每个 解析程序决定登录用户是否有权访问架构中的字段、查询或突变。
接下来
在下一课中,我们会后退一步,看看如何使用 GraphOS Studio来测试我们的身份验证设置。