概述
在前一个教程中,我们了解了如何通过登录到 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来测试我们的身份验证设置。