npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

redux-socket-auth-middleware

v1.0.3

Published

Redux socket authentication middleware

Readme

Redux socket.io authentication middleware


Redux middleware for handle socket.io authentication.

Inspiration from redux-promise-middleware.


Demo project: chat with authentication

Where should websockets and other persistent connections live?

Middleware are the right place for persistent connections like websockets in a Redux app, for several reasons:

  • Middleware exist for the lifetime of the application
  • Like with the store itself, you probably only need a single instance of a given connection that the whole app can use
  • Middleware can see all dispatched actions and dispatch actions themselves. This means a middleware can take dispatched actions and turn those into messages sent over the websocket, and dispatch new actions when a message is received over the websocket.

Given a single action with a socketIOClient.connect payload, the middleware transforms the action to a separate a pending action and a separate connected/rejected/disconnected action.

  import socketIOClient from 'socket.io-client';
    
  export const connectingToServer = () => ({
      type: 'SOCKET',
      payload: socketIOClient.connect(uri, opts),
    });

Installation

First, install the middleware:

npm i -S redux-socket-auth-middleware

Setup Store

Import the middleware and include it in applyMiddleware when creating the Redux store:

[TIP] You can also add redux-logger middleware.

  import {applyMiddleware, createStore} from 'redux';
  import socketAuth from 'redux-socket-auth-middleware';
  import logger from 'redux-logger';
  
  // Take our rootReducer/appReducer.
  import rootReducer from './reducers';
  
  // Apply middlewares, logger always in the end.
  const middleware = applyMiddleware(socketAuth, logger);
  
  // Create store with reducers and middlewares.
  const store = createStore(rootReducer, middleware);
  
  // Now we can use store in App
  export default store;

Action

Dispatch a socketIOClient.connect as the value of the payload property of the action.

  import socketIOClient from 'socket.io-client';
  
  // Type of action:
  const SOCKET = 'SOCKET';
  
  // URL where is running a server with socket.io
  const url = 'http://localhost:8000';
  
  // Function for connecting to a server
  // with that connection we passing query string: user 
  const connect = user => socketIOClient.connect(url, {query: `user=${user}`});
  
  // const user = JSON.stringify({name: 'Soda', password: 'secret'})
  export const connectingToServer = (user = null) => ({
    type: SOCKET,
    payload: connect(user),
  });
  
    /*  Now we can use this action in App
    * user argument hold name and password as object string
    * for adding into connection as query
    */
    
    // That's it for dispatch action!

Reducer

  // Action types suffixes for socket:
  const suffix = {
    PENDING: '_PENDING',
    CONNECTED: '_CONNECTED',
    REJECTED: '_REJECTED',
    DISCONNECTED: '_DISCONNECTED',
  };

  // Action type that dispatched connectingToServer action
  const SOCKET = 'SOCKET';

  // Initialization state:
  const initState = {
    disconnected: null,
    error: null,
    fetching: false,
    io: null,
  };
  
  // Reducer for handle socket.io connection.
  export default function socket(state = initState, {type, payload}) {
    switch (type) {
  
      // Handle action socket.io connecting to a server:
      case SOCKET + suffix.PENDING:
        return ({
          ...state,
          fetching: true,
        });
  
      // Handle action socket.io connected to a server:
      // payload hold connected socket.io.
      case SOCKET + suffix.CONNECTED:
        return ({
          ...state,
          io: payload,
          fetching: false,
        });
  
      // Handle action server rejected connection:
      // payload hold error from a server.
      case SOCKET + suffix.REJECTED:
        return ({
          ...state,
          error: payload,
          fetching: false,
        });
  
      // Handle action server disconnect client-socket:
      // payload hold reason disconnected from a server.
      case SOCKET + suffix.DISCONNECTED:
        return ({
          ...state,
          disconnected: payload,
          fetching: false,
        });
    }
  
    return state;
  }

  // That's it!

APP

  import React, {useState} from 'react';
  import {bindActionCreators} from 'redux';
  import {connect} from 'react-redux';
  // import redux action function for connecting to server
  import {connectingToServer} from '../path to redux action connectingToServer';
  
  function App({socket, connectingToServer}) {
    const [name, setName] = useState('');
    const [password, setPassword] = useState('');
    
    const handleChangeName = ({target}) => setName(target.value);
    const handleChangePassword = ({target}) => setPassword(target.value);
    
    const handleLogin = () => {
        const user = JSON.stringify({name, password});
        
        // Dispatch action 
        connectingToServer(user);
    };
    
    const renderStatus = () => (
      // If is a socket in redux store and is this socket connected.
      socket.io && socket.io.connected
        ? 'Connected'
        : 'Not connected'
    );
    
    // If is fetching from a server? 
    if (socket.fetching) return <h1>Loading...</h1>
      
    return (
      <div>
        <h1>{renderStatus()}</h1>
        <input value={name} onChange={handleChangeName}/>
        <input value={password} onChange={handleChangePassword}/> 
        <button onClick={handleLogin}>Login</button>
      </div>
    )
  }
  
  const mapStateToProps = ({socket}) => ({
    socket,
  });
  
 
  const mapDispatchToProps = dispatch => bindActionCreators({
    connectingToServer,
  }, dispatch);
  
  export default connect(mapStateToProps, mapDispatchToProps)(App);
  
          /* When we get a connection with a server:
           * redux store will hold socket.io,
           * so we can listen or emit events.
           * socket.io.on('some event', callback)
           * socket.io.emit('some event', arguments) 
           * just connect redux to component 
           * and mapStateToProps to get access to socket.io
           */

Server-side socket.io authentication

 io.use(function(socket, next) {
   var handshakeData = socket.request;
   // make sure the handshake data looks good as before
   // if error do this:
     // next(new Error('not authorized'));
   // else just call next
   next();
 });

Example of implementation.


Issues

For bug reports and feature requests, file an issue on GitHub.


License

Code licensed with the MIT License (MIT).