Skip to content

Commit d33c682

Browse files
unicodeveloperpeggyrayzis
authored andcommitted
Add image and authentication section
1 parent 20a777e commit d33c682

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

.DS_Store

6 KB
Binary file not shown.

docs/source/images/launches.png

258 KB
Loading

docs/source/tutorial/resolvers.md

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Mutation: {
7979

8080
As shown in the code above, there are three resolver functions, `bookTrip`, `cancelTrip`, and `login`.
8181

82-
The `bookTrip` function takes in a `launchId`,and makes a request to book a trip for that particular launch.
82+
The `bookTrip` function takes in a `launchId`, and makes a request to book a trip for that particular launch.
8383

8484
The `cancelTrip` function takes in a `launchId`, and makes a request via the `cancelTrip` method of the user data source to cancel a trip.
8585

@@ -123,8 +123,84 @@ The `trips` resolver function works like the steps outlined below:
123123

124124
<h2 id="write-query">Write a query in the playground</h2>
125125

126+
Apollo Server sets up GraphQL Playground so that you can start running queries and exploring schemas quickly. Go ahead and open the graph service URL in a browser, `http://localhost:4000/`.
126127

128+
Start by copying the query below and pasting it in the left side of the playground. After pasting, hit the Play button at the center to get a response.
129+
130+
```js
131+
query {
132+
launches {
133+
id
134+
year
135+
mission {
136+
name
137+
}
138+
}
139+
}
140+
```
141+
142+
A response like this should be returned at the right side of the playground.
143+
144+
![All Launches](../images/launches.png)
127145

128146
<h2 id="authentication">Authenticate users</h2>
129147

148+
Authentication is a common part of every application. There are several ways to handle authentication and authorization.
149+
150+
In this tutorial, we use a login token in an HTTP authorization header.
151+
152+
Update the `context` section of the `ApolloServer` constructor in `src/index.js` to have the code shown below:
153+
154+
_src/index.js_
155+
156+
```js
157+
...
158+
// Set up Apollo Server
159+
const server = new ApolloServer({
160+
...
161+
context: async ({ req }) => {
162+
// simple auth check on every request
163+
const auth = (req.headers && req.headers.authorization) || '';
164+
165+
const email = new Buffer(auth, 'base64').toString('ascii');
166+
167+
// if the email isn't formatted validly, return null for user
168+
if (!isEmail.validate(email)) return { user: null };
169+
// find a user by their email
170+
const users = await store.users.findOrCreate({ where: { email } });
171+
172+
const user = users && users[0] ? users[0] : null;
173+
174+
return { user: { ...user.dataValues } };
175+
},
176+
});
177+
```
178+
179+
In the `ApolloServer` constructor, we have a `context` function that takes in a request object. The context is usually generated again with every new request, so we can track the content of request headers on every request. The context function returns what we know as the `context` object. The `context` object is one that gets passed to every single resolver at every level, so we can access it anywhere in our schema code. We can store things like database connections, and user information in the `context` object.
180+
181+
In the code above, the context function extracts the value of the `authorization` header and stores it in an `auth` variable. It then verifies the value, which is a short token. The expected value is a valid email address. If the expected email address is valid, a request is made to check the database whether a user with that email address exists in the `users` table. If the user does not exist, a new user is created and a context object containing the logged-in user is returned to the resolvers.
182+
183+
If the user exists, a context object containing the logged-in user is returned to the resolver functions.
184+
185+
How do we create the token passed to the `authorization` headers? Check out the Query `login` resolver function again.
186+
187+
_src/resolvers.js_
188+
189+
```js
190+
...
191+
Mutation: {
192+
...
193+
login: async (root, { email }, { dataSources }) => {
194+
const user = await dataSources.userAPI.findOrCreateUser({ email });
195+
if (user) return new Buffer(email).toString('base64');
196+
return false;
197+
},
198+
...
199+
```
200+
201+
The `login` function receives an email address and checks the user table in the database if there's a user with that email address. If a user exists, the `login` function returns an an array containing the user object, else a new user is created.
202+
203+
Once a user object is present, the email is then converted to a base64 encoded string using the [Buffer](https://nodejs.org/api/buffer.html) class. The result is a short string token, that can now be sent to the server via an `authorization` header.
204+
205+
130206
<h2 id="testing">Test your graph</h2>

0 commit comments

Comments
 (0)