Skip to content

Commit 61ceebf

Browse files
Merge branch 'asmeikal-gql-subscriptions-auth'
2 parents 0176e04 + 0881f2d commit 61ceebf

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

content/graphql/subscriptions.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,49 @@ GraphQLModule.forRoot({
294294
}
295295
}),
296296
```
297+
298+
#### Authentication over WebSocket
299+
300+
Checking that the user is authenticated should be done inside the `onConnect` callback function that you can specify in the `subscriptions` options.
301+
302+
The `onConnect` will receive as a first argument the `connectionParams` passed to the `SubscriptionClient` (read [more](https://www.apollographql.com/docs/react/data/subscriptions/#5-authenticate-over-websocket-optional)).
303+
304+
```typescript
305+
GraphQLModule.forRoot({
306+
subscriptions: {
307+
'subscriptions-transport-ws': {
308+
onConnect: (connectionParams) => {
309+
const authToken = connectionParams.authToken;
310+
if (!isValid(authToken)) {
311+
throw new Error('Token is not valid');
312+
}
313+
// extract user information from token
314+
const user = parseToken(authToken);
315+
// return user info to add them to the context later
316+
return { user };
317+
},
318+
}
319+
},
320+
context: ({ connection }) => {
321+
// connection.context will be equal to what was returned by the "onConnect" callback
322+
},
323+
}),
324+
```
325+
326+
The `authToken` in this example is only sent once by the client, when the connection is first established.
327+
All subscriptions made with this connection will have the same `authToken`, and thus the same user info.
328+
329+
> warning **Note** There is a bug in `subscriptions-transport-ws` that allows connections to skip the `onConnect` phase (read [more](https://github.com/apollographql/subscriptions-transport-ws/issues/349)). You should not assume that `onConnect` was called when the user starts a subscription, and always check that the `context` is populated.
330+
331+
If you're using the `graphql-ws` package, the signature of the `onConnect` callback will be slightly different:
332+
333+
```typescript
334+
subscriptions: {
335+
'graphql-ws': {
336+
onConnect: (context: Context<any>) => {
337+
const { connectionParams } = context;
338+
// the rest will remain the same as in the example above
339+
},
340+
},
341+
},
342+
```

src/app/homepage/pages/microservices/custom-transport/custom-transport.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ <h4 appAnchor id="message-serialization"><span>Message serialization</span></h4>
197197
<p>If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the <code>ClientProxy</code> class or one of its child classes. For modifying successful requests you can override the <code>serializeResponse</code> method, and for modifying any errors that go through this client you can override the <code>serializeError</code> method. To make use of this custom class, you can pass the class itself to the <code>ClientsModule.register()</code> method using the <code>customClass</code> property. Below is an example of a custom <code>ClientProxy</code> that serializes each error into an <code>RpcException</code>.</p>
198198

199199
<span class="filename">
200-
{{ 'error-handling.proxy' | extension: appb508b379ce892494d97bbf7fb3f5093638c8e0a8.isJsActive }}
201-
<app-tabs #appb508b379ce892494d97bbf7fb3f5093638c8e0a8></app-tabs>
200+
{{ 'error-handling.proxy' | extension: app6d39c222a0bedd88c115e6126918ef05b8d10064.isJsActive }}
201+
<app-tabs #app6d39c222a0bedd88c115e6126918ef05b8d10064></app-tabs>
202202
</span><pre><code class="language-typescript">
203203
import &#123; ClientTcp, RpcException &#125; from &#39;@nestjs/microservices&#39;;
204204

@@ -210,8 +210,8 @@ <h4 appAnchor id="message-serialization"><span>Message serialization</span></h4>
210210
</code></pre><p>and then use it in the <code>ClientsModule</code> like so:</p>
211211

212212
<span class="filename">
213-
{{ 'app.module' | extension: app9edf2a86ee25caf1a636ec7b85e62ffa504bc949.isJsActive }}
214-
<app-tabs #app9edf2a86ee25caf1a636ec7b85e62ffa504bc949></app-tabs>
213+
{{ 'app.module' | extension: app58713f1e88f57e0ba10a9f3a0fbda5dfee0f3b97.isJsActive }}
214+
<app-tabs #app58713f1e88f57e0ba10a9f3a0fbda5dfee0f3b97></app-tabs>
215215
</span><pre><code class="language-typescript">
216216
@Module(&#123;
217217
imports: [

0 commit comments

Comments
 (0)