Redux Token Auth

0.19.0 · active · verified Wed Apr 22

Redux Token Auth is a specialized JavaScript library designed to facilitate client-side authentication for React and Redux applications integrating with Rails backends that utilize Devise Token Auth. Currently at version 0.19.0, it provides a comprehensive set of Redux Thunk actions for core authentication flows, including user registration, sign-in, sign-out, and token verification, alongside a dedicated Redux reducer to manage the authentication state. It also offers a higher-order component for safeguarding application routes, requiring `react-router v4.0.0+` for proper functionality. The library mandates the presence of `redux-thunk` middleware and manages user credentials by leveraging `localStorage` in browser environments, with `AsyncStorage` support for React Native applications planned for future releases. Its primary differentiator lies in its tailored API and conventions that align directly with the Devise Token Auth ecosystem.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates setting up the Redux store with `reduxTokenAuthReducer`, configuring `redux-token-auth` via `generateAuthActions`, dispatching initial credential verification, and simulating a user sign-in flow.

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { thunk } from 'redux-thunk'; // Standard ESM import for redux-thunk
import { reduxTokenAuthReducer, generateAuthActions } from 'redux-token-auth';

// 1. Redux Store Setup
const rootReducer = combineReducers({
  reduxTokenAuth: reduxTokenAuthReducer,
  // ... potentially other reducers
});

// Define a minimal initial state structure matching redux-token-auth's expectations
const initialState = {
  reduxTokenAuth: {
    currentUser: {
      isLoading: false,
      isSignedIn: false,
      attributes: {}, // Example: firstName: null
    },
  },
  // ... any other initial state needed by other reducers
};

// Create the Redux store
// Note: In a modern React/Redux app, you'd typically use configureStore from @reduxjs/toolkit
const store = createStore(rootReducer, initialState as any, applyMiddleware(thunk));

// 2. Configure redux-token-auth and generate actions
const config = {
  apiBase: 'https://api.example.com/v1', // IMPORTANT: Replace with your actual Devise Token Auth API base URL
  signOutPath: '/auth/sign_out',
  signInPath: '/auth/sign_in',
  signUpPath: '/auth',
  userAttributes: {
    firstName: 'first_name',
    lastName: 'last_name',
    email: 'email',
  },
  storage: typeof window !== 'undefined' ? localStorage : null, // Use localStorage in browser, null otherwise
  // You can also add authProviderPaths, etc., as needed
};

// Generate the auth actions and the verifyCredentials helper
const {
  registerUser,
  signInUser,
  signOutUser,
  verifyToken,
  verifyCredentials,
} = generateAuthActions(config);

console.log('Redux Store initialized and auth actions generated.');

// 3. Dispatch verifyCredentials on application load
// This ensures the app checks for existing user tokens on startup
if (config.storage) { // Only attempt if localStorage is available (i.e., not server-side rendering)
    store.dispatch(verifyCredentials() as any);
    console.log('Dispatched verifyCredentials on app startup.');
}

// Example: Simulate a sign-in attempt (in a real app, this would be triggered by a user action)
async function simulateSignIn() {
  console.log('\n--- Simulating User Sign-In ---');
  try {
    const signInPayload = { email: 'user@example.com', password: 'password123' };
    // Dispatch the signInUser thunk action
    // Note: Type assertion `as any` is used here for simplicity in quickstart,
    // in a real app, proper ThunkAction types would be used.
    await store.dispatch(signInUser(signInPayload) as any);
    console.log('Sign-in successful. Current auth state:', store.getState().reduxTokenAuth.currentUser);
  } catch (error: any) {
    console.error('Sign-in failed:', error.response?.data || error.message);
  }
}

// Call the simulation
if (typeof window !== 'undefined') {
    // Only run this client-side for demonstration
    simulateSignIn();
}

// To use generateRequireSignInWrapper, you would typically use it within a React component:
// import { generateRequireSignInWrapper } from 'redux-token-auth';
// const MyProtectedComponent = () => <div>Protected Content!</div>;
// const RequireSignIn = generateRequireSignInWrapper({
//   redirectPath: '/login', // Path to redirect if not signed in
//   WrappedComponent: MyProtectedComponent,
// });
// In your router: <Route path="/dashboard" component={RequireSignIn} />

console.log('\nQuickstart complete. Check console for output.');

view raw JSON →