Authenticating Communication

Let’s have a look at how to use WebSockets to enable authentication in our application.

We'll cover the following

Handling authentication with WebSockets can be tricky, WebSockets are used alongside regular HTTP requests in many applications. The authentication will usually be done via regular REST or OAUTH calls. The front end will grant a token either set in cookies or saved in localStorage.

A special agreed-upon action has to be sent by the client to allow the server to authenticate a WebSocket. In Redux, a special action object can be serialized and sent before doing any other work over WebSockets.

Sample flow

A simple way to implement authentication might be to send an API action to our server containing an email address and a password:

// Action to authenticate with the server
dispatch({
  type: API,
  payload: {
    url: 'login',
    method: 'POST',
    success: loggedIn,
    data: {
      email: 'info@redux-book.com',
      password: 'top secret'
    }
  }
});

If successful, our API middleware will dispatch the LOGIN_SUCCESS action containing the information returned from the server:

// Action dispatched on successful login
{
  type: LOGGED_IN,
  payload: { token: 'xxxYYYzzzz' }
}

Our user’s reducer will probably act on this action to add the token to the state and pass in the headers of future API requests to the server.

To make WebSockets authenticate using this token, we can add special code to our WebSocket API that will act upon LOGGED_IN and LOGOUT actions:

// Authentication code in the WebSocket middleware
if (action.type === LOGGED_IN) {
  dispatch({
    type: WEBSOCKET_AUTH,
    payload: action.payload.token,
    meta: { websocket: true }
  });
}

if (action.type === LOGOUT) {
  dispatch({
    type: WEBSOCKET_LOGOUT,
    meta: { websocket: true }
  });
}

Now the passage of LOGGED_IN will cause a new WebSocket-enabled action to be dispatched and processed by our middleware to authenticate with the server:

// The flow of actions

//store receives API dispatch
> Store:
{ type: API, payload: ... }

//server receives POST request
> Server:
POST http://.../login

//store receives LOGGEED_IN dispatch
> Store:
{ type: LOGGED_IN, payload: token }

//store receives WEBSOCKET_AUTH dispatch
> Store:
{ type: WEBSOCKET_AUTH, payload: token, meta: { websocket: true }}

//websocket receives WEBSOCKET_AUTH dispatch
> WebSocket:
{ type: WEBSOCKET_AUTH, payload: token }

Get hands-on with 1200+ tech skills courses.