Skip to content

Commit 56229c8

Browse files
authored
Merge pull request graphql#67 from robzhu/new-source
Add Best Practices: Authorization
2 parents e591d85 + 323de1b commit 56229c8

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

site/learn/BestPractice-Authorization.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,56 @@ title: Authorization
33
layout: ../_core/DocsLayout
44
category: Best Practices
55
permalink: /learn/authorization/
6+
next: /learn/serving-over-http/
67
---
78

8-
WIP
9+
> Delegate authorization logic to the business logic layer
10+
11+
Authorization is a type of business logic that describes whether a given user/session/context has permission to perform an action or see a piece of data. For example:
12+
13+
*“Only authors can see their drafts”*
14+
15+
Enforcing this kind of behavior should happen in the [business logic layer](/learn/thinking-in-graphs/#business-logic-layer). It is tempting to place authorization logic in the GraphQL layer like so:
16+
17+
```javascript
18+
var postType = new GraphQLObjectType({
19+
name: ‘Post’,
20+
fields: {
21+
body: {
22+
type: GraphQLString,
23+
resolve: (post, args, context, rootValue) => {
24+
// return the post body only if the user is the post's author
25+
if (context.user && (context.user.id === post.authorId)) {
26+
return post.body;
27+
}
28+
return null;
29+
}
30+
}
31+
}
32+
});
33+
```
34+
35+
Notice that we define “author owns a post" by checking whether the post's `authorId` field equals the current user’s `id`. Can you spot the problem? We would need to duplicate this code for each entry point into the service. Then if the authorization logic is not kept perfectly in sync, users could see different data depending on which API they use. Yikes! We can avoid that by having a [single source of truth](/learn/thinking-in-graphs/#business-logic-layer) for authorization.
36+
37+
Defining authorization logic inside the resolver is fine when learning GraphQL or prototyping. However, for a production codebase, delegate authorization logic to the business logic layer. Here’s an example:
38+
39+
```javascript
40+
//Authorization logic lives inside postRepository
41+
var postRepository = require('postRepository');
42+
43+
var postType = new GraphQLObjectType({
44+
name: ‘Post’,
45+
fields: {
46+
body: {
47+
type: GraphQLString,
48+
resolve: (post, args, context, rootValue) => {
49+
return postRepository.getBody(context.user, post);
50+
}
51+
}
52+
}
53+
});
54+
```
55+
56+
In the example above, we see that the business logic layer requires the caller to provide a user object. If you are using GraphQL.js, the User object should be populated on the `context` or `rootValue` arguments of the resolver.
57+
58+
We recommend passing a fully-hydrated User object instead of an opaque token or API key to your business logic layer. This way, we can handle the distinct concerns of [authentication](/graphql-js/authentication-and-express-middleware/) and authorization in different stages of the request processing pipeline.

site/learn/BestPractice-ServingOverHTTP.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ title: Serving over HTTP
33
layout: ../_core/DocsLayout
44
category: Best Practices
55
permalink: /learn/serving-over-http/
6-
next: /learn/authorization/
76
---
87

98
HTTP is the most common choice for client-server protocol when using GraphQL because of its ubiquity. Here are some guidelines for setting up a GraphQL server to operate over HTTP.
@@ -49,7 +48,7 @@ A standard GraphQL POST request should use the `application/json` content type,
4948
}
5049
```
5150

52-
`operationName` and `variables` are optional fields. `operationName` is only required if multiple operations are present in the query.
51+
`operationName` and `variables` are optional fields. `operationName` is only required if multiple operations are present in the query.
5352

5453
In addition to the above, we recommend supporting two additional cases:
5554

site/learn/Learn-Schema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Schemas and Types
33
layout: ../_core/DocsLayout
44
category: Learn
55
permalink: /learn/schema/
6-
next: /learn/serving-over-http/
6+
next: /learn/thinking-in-graphs/
77
sublinks: type-system,type-language,object-types-and-fields,arguments,the-query-and-mutation-types,scalar-types,enumeration-types,lists-and-non-null,interfaces,union-types,input-types
88
---
99

0 commit comments

Comments
 (0)