You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: site/learn/BestPractice-Authorization.md
+51-1Lines changed: 51 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,56 @@ title: Authorization
3
3
layout: ../_core/DocsLayout
4
4
category: Best Practices
5
5
permalink: /learn/authorization/
6
+
next: /learn/serving-over-http/
6
7
---
7
8
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 =newGraphQLObjectType({
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
+
returnpost.body;
27
+
}
28
+
returnnull;
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 =newGraphQLObjectType({
44
+
name: ‘Post’,
45
+
fields: {
46
+
body: {
47
+
type: GraphQLString,
48
+
resolve: (post, args, context, rootValue) => {
49
+
returnpostRepository.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.
Copy file name to clipboardExpand all lines: site/learn/BestPractice-ServingOverHTTP.md
+1-2Lines changed: 1 addition & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,6 @@ title: Serving over HTTP
3
3
layout: ../_core/DocsLayout
4
4
category: Best Practices
5
5
permalink: /learn/serving-over-http/
6
-
next: /learn/authorization/
7
6
---
8
7
9
8
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,
49
48
}
50
49
```
51
50
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.
53
52
54
53
In addition to the above, we recommend supporting two additional cases:
0 commit comments