Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Pusher authorized connections #7965

Closed
wants to merge 18 commits into from
104 changes: 100 additions & 4 deletions broadcasting.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Defining Authorization Routes](#defining-authorization-routes)
- [Defining Authorization Callbacks](#defining-authorization-callbacks)
- [Defining Channel Classes](#defining-channel-classes)
- [Defining Authorized Connections](#defining-authorized-connections)
- [Broadcasting Events](#broadcasting-events)
- [Only To Others](#only-to-others)
- [Customizing The Connection](#customizing-the-connection)
Expand Down Expand Up @@ -515,13 +516,13 @@ Private channels require you to authorize that the currently authenticated user
<a name="defining-authorization-routes"></a>
### Defining Authorization Routes

Thankfully, Laravel makes it easy to define the routes to respond to channel authorization requests. In the `App\Providers\BroadcastServiceProvider` included with your Laravel application, you will see a call to the `Broadcast::routes` method. This method will register the `/broadcasting/auth` route to handle authorization requests:
Thankfully, Laravel makes it easy to define the routes to respond to channel authorization requests. In the `App\Providers\BroadcastServiceProvider` included with your Laravel application, you will see a call to the `Broadcast::channelAuthorizationRoutes` method. This method will register the `/broadcasting/auth` route to handle authorization requests:
rennokki marked this conversation as resolved.
Show resolved Hide resolved

Broadcast::routes();
Broadcast::channelAuthorizationRoutes();

The `Broadcast::routes` method will automatically place its routes within the `web` middleware group; however, you may pass an array of route attributes to the method if you would like to customize the assigned attributes:
The `Broadcast::channelAuthorizationRoutes` method will automatically place its routes within the `web` middleware group; however, you may pass an array of route attributes to the method if you would like to customize the assigned attributes:

Broadcast::routes($attributes);
Broadcast::channelAuthorizationRoutes($attributes);

<a name="customizing-the-authorization-endpoint"></a>
#### Customizing The Authorization Endpoint
Expand Down Expand Up @@ -649,6 +650,101 @@ Finally, you may place the authorization logic for your channel in the channel c

> {tip} Like many other classes in Laravel, channel classes will automatically be resolved by the [service container](/docs/{{version}}/container). So, you may type-hint any dependencies required by your channel in its constructor.

<a name="defining-user-authentication-routes"></a>
### Defining User Authentication Routes

> {tip} This feature is supported only by the `pusher` driver and needs to be explicitly enabled from your Pusher app. Your Pusher SDKs must also be updated to 7.1+ and your Laravel Echo should be to the latest version.

While you can authorize your connections to access specific channels, you can also restrict the connections only for your authenticated users. This can be useful in case you have no publicly-exposed channels and you want to prevent anyone from maliciously using your app key to spawn a lot of browsers, consuming your connections quota.

When enabled, in case the user does not subscribe to any private or presence channel in the first few seconds after connection, you shall attempt to authorize.

Thankfully, Laravel makes it easy to define the routes to respond to user authentication requests. In the `App\Providers\BroadcastServiceProvider` included with your Laravel application, you will see a call to the `Broadcast::userAuthenticationRoutes` method. This method will register the `/broadcasting/user-auth` route to handle authorization requests:

Broadcast::userAuthenticationRoutes();

The `Broadcast::userAuthenticationRoutes` method will automatically place its routes within the `web` middleware group; however, you may pass an array of route attributes to the method if you would like to customize the assigned attributes:

Broadcast::userAuthenticationRoutes($attributes);

<a name="defining-authorized-connections"></a>
### Defining Authorized Connections

You can configure the frontend Pusher app to send an HTTP request to `/broadcasting/user-auth`. Laravel allows you on the backend side to define the user details in the `boot` method of `\App\Providers\BroadcastServiceProvider` so you can share with Pusher the authentication details.

```php
Broadcast::resolveAuthenticatedUserUsing(function ($request) {
return [
'id' => $request->user()->id,
'name' => $request->user()->name,
];
});
```

You can as well reject WebSocket connections by returning `null`:

```php
Broadcast::resolveAuthenticatedUserUsing(function ($request) {
if ($request->user()->isBanned()) {
return null;
}

return [
'id' => $request->user()->id,
'name' => $request->user()->name,
];
});
```

> {tip} The returned object MUST contain the `id` field. The value of this field will be the unique identifier of the authenticatable model that Pusher will use for other actions, such as sending events only to that user.

Authentication is performed automatically if your users join a private or presence channel immediately after connection. However, you may sometimes initiate a connection without subscribing to an authorization-protected channel. If the authentication is enabled the latter scenario will eventually make your users disconnect without the possibility of reconnection without a refresh.

In order to perform the authentication in your frontend and explicitly tell Pusher to check the user, you shall call `.signin()` from Echo:

```js
Echo.signin();
```

<a name="customizing-the-user-authentication-endpoint"></a>
#### Customizing The User Authentication Endpoint

By default, Echo will use the `/broadcasting/user-auth` endpoint to authenticate users' connection. However, you may specify your own authentication endpoint by passing the `userAuthentication.endpoint` configuration option to your Echo instance:

```js
window.Echo = new Echo({
broadcaster: 'pusher',
// ...
userAuthentication: {
endpoint: '/custom/endpoint/auth',
},
});
```

<a name="customizing-the-user-authentication-request"></a>
#### Customizing The User Authentication Request

You can customize how Laravel Echo performs authorization requests by providing a custom authorizer when initializing Echo:

```js
window.Echo = new Echo({
// ...
userAuthentication: {
customHandler: ({ socketId }, callback) => {
axios.post('/api/broadcasting/user-auth', { socket_id: socketId })
.then(response => {
callback(false, response.data);
})
.catch(error => {
callback(true, error);
});
},
},
});
```

You can read more about authorized connections on the [Pusher website](https://pusher.com/docs/channels/using_channels/authorized-connections/).

<a name="broadcasting-events"></a>
## Broadcasting Events

Expand Down