Keeping things private: Authentication vs. Authorization
One of the great benefits of using Pusher’s APIs is that it is really simple to subscribe to channels that require permission to join. This means that you can use Channels and Beams to safely deliver sensitive messages to the right users only.
This is great for use cases like 1:1 and group chat where you want to restrict the participant list, or personalised notification systems such as order/delivery tracking and in-app notifications where only a specific user should be able to access their orders or notifications.
As an example, imagine you had a chat platform with private group chats such as #supersecretchat. If you were using public channels there would be nothing to stop any user from joining this channel and intercepting all messages even if they weren’t part of the intended audience. By joining a private channel each user must present a valid access token before joining.
Implementing private channels
When you make a subscription to a channel prefixed with a private- an authorizarion step is required to get an access token from your server as shown:
When pusher.subscribe(private-channel) is called a callback is made to an authentication endpoint of your choice. This endpoint will check that the user is allowed to join the channel and if so return an access token.
However there are a couple of concepts that are important to understand to make sure that only users with permission can join restricted channels. This is based on authentication vs authorization.
Building on from the example above, imagine you had a chat app that required users to register and login using an email and password. A user such as [email protected] may log in to your app and your server may issue something like a session token so the user can continue to identify themselves without repeatedly having to provide their email and password.
If a user then wanted to join a restricted private channel they would make a callback to your Channels authentication endpoint and provide the session token you had provided to them earlier.
By providing the session token, the user is proving to the authentication endpoint that they are a valid user of your app and have a registered identity. This is what we mean by authentication.
Let’s assume that anyone can register for your chat app but not everyone can join the #supersecretchat channel. It isn’t enough for your app endpoint to issue access tokens to any user with a valid session token. Otherwise users that have not been invited could potentially gain access to the #supersecretchat channel and be privy to information they should not be able to access.
This leads on to the next consideration; authorization. Once you have proven that a user has a valid session in your chat app, you then need to look up what channels this user is entitled to participate in.
For example user lets say [email protected] requests to join #supersecretchat. You have already checked that the session token they have provided is valid and therefore the requesting user is indeed jbloggs.
The next step is to check to see if [email protected] is a valid participant in #supersecretchat. If they are only at this point would you return an access token for this channel.
If you want to explore this concept further you should look at our three part tutorial series where we demonstrate how to set up authentication via Github and an example of authorizing a user to join a user specific channel.