Mastering User Authentication in React JS using JWT

Mastering User Authentication in React JS using JWT

To use JWT (JSON Web Token) for authentication, modify your authentication flow to create, validate, and store JWT tokens. This updated example demonstrates JWT token authentication in a React application with a simple Express backend using JSON Web Tokens.

Backend Setup (Node.js and Express):

  1. Install required packages:
npm install express jsonwebtoken
  1. Create a simple Express server (server.js):
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');

const app = express();
const port = 3001;

app.use(bodyParser.json());

const secretKey = 'your-secret-key';

app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // Validate the username and password (this is a simplified example)
  if (username === 'example_user' && password === 'password') {
    // Create a JWT token
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });

    res.json({ token });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

React Frontend:

  1. Install required packages:
npm install react-router-dom axios
  1. Create an AuthContext.js for managing authentication:
// AuthContext.js
import { createContext, useContext, useState } from 'react';
import axios from 'axios';

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const login = async (username, password) => {
    try {
      // Make API request to login endpoint on the server
      const response = await axios.post('http://localhost:3001/login', {
        username,
        password,
      });

      const { token } = response.data;

      // Store the token in localStorage or a secure storage method
      localStorage.setItem('token', token);

      // Decode the token to get user information (this is a simplified example)
      const decodedToken = jwt.decode(token);

      setUser({ username: decodedToken.username });
    } catch (error) {
      console.error('Login failed', error);
    }
  };

  const logout = () => {
    // Clear user state
    setUser(null);

    // Remove token from localStorage or secure storage
    localStorage.removeItem('token');
  };

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => {
  return useContext(AuthContext);
};
  1. Update your login and logout components:
// LoginComponent.js
import { useAuth } from './AuthContext';

const LoginComponent = () => {
  const { login } = useAuth();

  const handleLogin = () => {
    // Call the login function with username and password
    login('example_user', 'password');
  };

  return (
    <div>
      <h2>Login</h2>
      <button onClick={handleLogin}>Login</button>
    </div>
  );
};

export default LoginComponent;
// LogoutComponent.js
import { useAuth } from './AuthContext';

const LogoutComponent = () => {
  const { logout } = useAuth();

  const handleLogout = () => {
    // Call the logout function
    logout();
  };

  return (
    <div>
      <h2>Logout</h2>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
};

export default LogoutComponent;
  1. Update your App component to use the AuthProvider:
// App.js
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import PrivateRoute from './PrivateRoute';
import LoginComponent from './LoginComponent';
import LogoutComponent from './LogoutComponent';
import ExampleComponent from './ExampleComponent';

const App = () => {
  return (
    <Router>
      <AuthProvider>
        <Switch>
          <Route path="/login" component={LoginComponent} />
          <Route path="/logout" component={LogoutComponent} />
          <PrivateRoute path="/protected" component={ExampleComponent} />
          {/* Other public routes */}
        </Switch>
      </AuthProvider>
    </Router>
  );
};

export default App;

Conclusion:

Ensure that you keep your JWT token secure in real-life situations. Use HTTPS, set up token refresh mechanisms, and handle token expiration properly. Consider using a library like jsonwebtoken in the backend for token verification. Always adhere to the best practices for securing JWT tokens.