將授權邏輯委派給商業邏輯層
授權是一種商業邏輯,描述特定使用者/工作階段/內容是否有權限執行動作或查看資料。例如
「只有作者才能看到他們的草稿」
執行這種行為應在 商業邏輯層 中進行。將授權邏輯放在 GraphQL 層中很誘人,如下所示
var postType = new GraphQLObjectType({ name: ‘Post’, fields: { body: { type: GraphQLString, resolve: (post, args, context, { rootValue }) => { // return the post body only if the user is the post's author if (context.user && (context.user.id === post.authorId)) { return post.body; } return null; } } }});
請注意,我們透過檢查貼文的 authorId
欄位是否等於目前使用者的 id
來定義「作者擁有貼文」。你能找出問題嗎?我們需要為服務中的每個進入點複製這段程式碼。然後,如果授權邏輯沒有完全同步,使用者可能會根據他們使用的 API 看到不同的資料。糟糕!我們可以透過擁有授權的 單一真實來源 來避免這種情況。
在學習 GraphQL 或製作原型時,在解析器中定義授權邏輯是可以的。但是,對於製作環境程式碼庫,請將授權邏輯委派給商業邏輯層。以下是一個範例
//Authorization logic lives inside postRepositoryvar postRepository = require('postRepository');
var postType = new GraphQLObjectType({ name: ‘Post’, fields: { body: { type: GraphQLString, resolve: (post, args, context, { rootValue }) => { return postRepository.getBody(context.user, post); } } }});
在上面的範例中,我們看到商業邏輯層要求呼叫者提供使用者物件。如果您使用 GraphQL.js,則應在解析器的第四個引數中的 context
引數或 rootValue
中填入 User 物件。
我們建議傳遞一個完全水合的使用者物件,而不是不透明的權杖或 API 金鑰給您的業務邏輯層。這樣,我們可以在請求處理管線的不同階段處理 驗證 和授權的明確問題。