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

v4.2.0

Published

Typescript Redux socket authentication

Readme

Redux Socket Auth

Opionated full user/authentication/ACL solution for projects with:

  • React
  • React-router
  • Redux
  • Websockets

Features:

  • Signup
  • Login/logout
  • Stores a session token in local storage to automatically resume sessions
  • Defining routes that are only accessible for logged in users
  • ACL: define per route which roles can access it
  • All communication with the server happens over web sockets

Warning: because this is an opionated, fully functional solution, you will need to configure your server in a very specific way.

Dependencies

There are a number of peer dependencies that your project needs to include:

  • react
  • react-redux
  • react-router-dom
  • redux
  • redux-reconnecting-socket

Server config (API spec)

Messages from client -> to server

LOGIN

{
    type: 'LOGIN',
    payload: {
        // note that the payload here can be anything you like, as long
        // as the server responds with a payload like:
        // { jwtToken: 'my_jwt_token' }
        // (more details in LOGIN_RESPONSE)
        username: 'test',
        password: 'secret'
    }
}

RESUME_SESSION

{
    type: 'RESUME_SESSION',
    payload: {
        jwtToken: 'my_jwt_token'
    }
}

SIGN_UP

{
    type: 'SIGN_UP',
    payload: {
        // note that the payload here can be anything you like, as long
        // as the server responds with a payload like:
        // { jwtToken: 'my_jwt_token' }
        // (more details in SIGN_UP_RESPONSE)
        username: 'test',
        password: 'secret'
    }
}

Messages from server -> to client

LOGIN_RESPONSE

{
    type: 'LOGIN_RESPONSE',
    error: false, // use true if it failed
    payload: {
        jwtToken: 'my_jwt_token',
        user: {
            role: 'admin', // optional
            // other properties are allowed, but not relevant to this
            // module
        }
    }
}

RESUME_SESSION_RESPONSE

{
    type: 'RESUME_SESSION_RESPONSE',
    error: false, // use true if it failed
    payload: {
        jwtToken: 'my_jwt_token',
        user: {
            role: 'admin', // optional
            // other properties are allowed, but not relevant to this
            // module
        }
    }
}

SIGN_UP_RESPONSE

{
    type: 'SIGN_UP_RESPONSE',
    error: false, // use true if it failed
    payload: {
        jwtToken: 'my_jwt_token',
        user: {
            role: 'admin', // optional
            // other properties are allowed, but not relevant to this
            // module
        }
    }
}

You might have noticed that LOGIN_RESPONSE, RESUME_SESSION_RESPONSE and SIGN_UP_RESPONSE have identical message structures. This is correct.

Clientside installation

1. Installation

npm install redux-socket-auth

2. Configuring the middleware

import { reduxSocketAuth } from 'redux-socket-auth';

const store = createStore(
    rootReducer(history),
    initialState,
    composeEnhancer(
        applyMiddleware(
            routerMiddleware(history),
            reduxSocketAuth(),
            reduxReconnectingSocket(),
        ),
    )
);

3. Configuring the reducer

import { reduxSocketAuthReducer } from 'redux-socket-auth';

export const rootReducer = (history) => combineReducers({
    router: connectRouter(history),
	connection: reduxReconnectingSocketReducer,
	reduxSocketAuth: reduxSocketAuthReducer
});

4. Defining routes

import { Switch, Route } from 'react-router-dom';
import { AuthRoute, UnauthRoute } from 'redux-socket-auth';

class App extends React.Component {
    render() {
        const { isAuthenticating, connected } = this.props;

        if (isAuthenticating || !connected) {
            // This is required!
            // Otherwise the user would get redirected to the login form
            // before the authentication process is completed
            return 'Fancy loading spinner';
        }

        return (
            <Switch>
                <AuthRoute
                    exact={true}
                    component={MyProtectedComponent}
                    path="/protected"
                    redirectTo="/login"
                />
                <AuthRoute
                    exact={true}
                    component={AdminsOnlyComponent}
                    path="/admins-only"
                    redirectTo="/login"
                    roles={['admin']}
                />
                <UnauthRoute
                    exact={true}
                    component={LoginForm}
                    path="/login"
                    redirectTo="/protected"
                />
                <Route
                    exact={true}
                    component={MyPublicComponent}
                    path="/always-accessible"
                />
            </Switch>
        );
    }
}

const select = (state) => ({
    isAuthenticating: state.reduxSocketAuth.isAuthenticating,
    connected: state.connection.connected
});

export default connect(select)(App);

5. Signing up

import { signUp } from 'redux-socket-auth';

class SignUpForm extends React.Component {
    ...

    onSubmit() {
        const { dispatch } = this.props;
        const { username, password, email, name } = this.state;

        const promise = dispatch(signUp({
            username,
            password,
            email,
            name
        }));

        promise.then(() => {
            // Redirect the user after successful signup
            history.push('/dashboard');
        });

        promise.catch(messageFromServer =>
            this.setState({ errors: JSON.stringify(messageFromServer) })
        );
    }

    ...
}

6. Logging in

import { login } from 'redux-socket-auth';

class LoginForm extends React.Component {
    ...

    onSubmit() {
        const { dispatch } = this.props;
        const { username, password } = this.state;

        const promise = dispatch(login({ username, password }));

        promise.then(() => {
            // Redirect the user after successful login
            history.push('/dashboard');
        });

        promise.catch(messageFromServer =>
            this.setState({ errors: JSON.stringify(messageFromServer) })
        );
    }

    ...
}

7. Logging out

import { logout } from 'redux-socket-auth';

class LogoutButton extends React.Component {
    ...

    onClick() {
        const { dispatch } = this.props;

        dispatch(logout());
    }

    ...
}

8. Displaying user info

class UserInfo extends React.Component {
    render() {
        const { user } = this.props;

        return (
            <p>{user.name}</p>
        }
    }
}

const select = (state) => ({
    user: state.reduxSocketAuth.user
});

export default connect(select)(UserInfo);

9. Updating the user

import { updateUser } from 'redux-socket-auth';

dispatch(updateUser({ email: '[email protected]', name: 'test' }));

10. Email confirmation

Typically you might send a confirmation email to a new user after they sign up. The confirmation email contains a token.

Step 1: Get the token from the URL and save it in the store

import { setConfirmEmailToken } from 'redux-socket-auth';

dispatch(setConfirmEmailToken(urlParams.get('token')));

Step 2: When the user logs in (or resumes his session), the CONFIRM_EMAIL action with the token will automatically be sent to the server.

11. Resending verification email

import { verifyEmail } from 'redux-socket-auth';

dispatch(verifyEmail());