Home > Web Front-end > JS Tutorial > Authentication with express js and react js unsing jwt

Authentication with express js and react js unsing jwt

Patricia Arquette
Release: 2024-10-05 12:18:31
Original
662 people have browsed it

Authentication with express js and react js unsing jwt

To create an authentication system using React.js on the frontend, Express.js on the backend we need to implement the following:

  • Frontend (React.js with Pulsy): Handle login and logout, maintain user authentication state, and persist tokens.
  • Backend (Express.js): Provide authentication endpoints (e.g., login, logout, user validation).

Step 1: Backend (Express.js) Setup

Let's start with the backend to handle user authentication and token generation.

Install Required Packages


npm install express bcryptjs jsonwebtoken cors


Copy after login

Backend Code (Express.js)

Create an authController.js file to handle authentication logic:


// authController.js
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

// Mock user data (in production, you would use a real database)
const users = [
  {
    id: 1,
    username: 'john',
    password: '$2a$10$O1s8iLKRLPbPqhc1uTquLO.xODTC1U/Z8xGoEDU6/Dc0PAQ3MkCKy', // hashed password for 'password123'
  },
];

// JWT Secret
const JWT_SECRET = 'supersecretkey';

exports.login = (req, res) => {
  const { username, password } = req.body;

  const user = users.find((u) => u.username === username);

  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  bcrypt.compare(password, user.password, (err, isMatch) => {
    if (isMatch) {
      // Create a token
      const token = jwt.sign({ id: user.id, username: user.username }, JWT_SECRET, { expiresIn: '1h' });
      return res.json({ token });
    } else {
      return res.status(401).json({ error: 'Invalid credentials' });
    }
  });
};

exports.validateToken = (req, res) => {
  const token = req.header('Authorization').replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({ error: 'No token provided' });
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    res.json({ user: { id: decoded.id, username: decoded.username } });
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};


Copy after login

Next, create the main server.js file for setting up Express:


// server.js
const express = require('express');
const cors = require('cors');
const { login, validateToken } = require('./authController');

const app = express();
app.use(express.json());
app.use(cors());

// Authentication routes
app.post('/api/login', login);
app.get('/api/validate', validateToken);

// Start the server
const PORT = 5000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});


Copy after login
  • POST /api/login: Authenticates a user and returns a JWT token.
  • GET /api/validate: Validates a token and returns the user info.

Step 2: Frontend (React.js with Pulsy)

Now let's set up the frontend using React.js and Pulsy to handle the authentication state.

Install Required Packages


npm install axios pulsy


Copy after login

Pulsy Store Setup

We will create a Pulsy store to manage authentication state globally.


// authStore.js
import { createStore, addMiddleware } from 'pulsy';
import axios from 'axios';

// Create a store to hold the user and token
createStore('auth', {
  user: null,
  token: null,
}, { persist: true }); // Persist the auth state in localStorage

// Middleware to add Authorization header for authenticated requests
addMiddleware('auth', (nextValue, prevValue, storeName) => {
  if (nextValue.token) {
    axios.defaults.headers.common['Authorization'] = `Bearer ${nextValue.token}`;
  } else {
    delete axios.defaults.headers.common['Authorization'];
  }
  return nextValue;
});


Copy after login

This store will persist the authentication state (user and token) and automatically apply the Authorization header for authenticated requests.

Authentication Functions

Create helper functions to handle login and validation requests:


// authService.js
import { setStoreValue } from 'pulsy';
import axios from 'axios';

const API_URL = 'http://localhost:5000/api';

export const login = async (username, password) => {
  try {
    const response = await axios.post(`${API_URL}/login`, { username, password });
    const { token } = response.data;

    // Set token and user info in Pulsy store
    setStoreValue('auth', { token, user: { username } });

    return true;
  } catch (error) {
    console.error('Login failed', error);
    return false;
  }
};

export const validateToken = async () => {
  try {
    const response = await axios.get(`${API_URL}/validate`);
    const user = response.data.user;

    // Update the store with the user info
    setStoreValue('auth', { user, token: localStorage.getItem('auth_token') });
    return true;
  } catch (error) {
    console.error('Token validation failed', error);
    return false;
  }
};

export const logout = () => {
  setStoreValue('auth', { user: null, token: null });
  localStorage.removeItem('pulsy_auth');
};


Copy after login

Step 3: Create Authentication Components

Now let’s create the React components for login and authenticated views.

Login Component


// Login.js
import React, { useState } from 'react';
import { login } from './authService';

const Login = () => {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleLogin = async (e) => {
    e.preventDefault();
    const success = await login(username, password);
    if (!success) {
      setError('Invalid credentials. Try again.');
    }
  };

  return (
    <div>
      <h2>Login</h2>
      <form onSubmit={handleLogin}>
        <input
          type="text"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          placeholder="Username"
          required
        />
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          placeholder="Password"
          required
        />
        <button type="submit">Login</button>
      </form>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
};

export default Login;


Copy after login

Authenticated Component


// Dashboard.js
import React from 'react';
import { usePulsy } from 'pulsy';
import { logout } from './authService';

const Dashboard = () => {
  const [auth] = usePulsy('auth');

  const handleLogout = () => {
    logout();
    window.location.reload(); // Simple page refresh to redirect to login
  };

  return (
    <div>
      <h2>Welcome, {auth.user.username}!</h2>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
};

export default Dashboard;


Copy after login

Step 4: App Component

In the App.js component, you’ll want to check if the user is authenticated and conditionally render either the login or dashboard.


// App.js
import React, { useEffect } from 'react';
import { usePulsy } from 'pulsy';
import { validateToken } from './authService';
import Login from './Login';
import Dashboard from './Dashboard';

function App() {
  const [auth] = usePulsy('auth');

  useEffect(() => {
    // Check token validity on app load
    if (auth.token) {
      validateToken();
    }
  }, [auth.token]);

  return (
    <div className="App">
      {auth.user ? <Dashboard /> : <Login />}
    </div>
  );
}

export default App;


Copy after login

Step 5: Run the Application

Now that we have both the backend and frontend set up, you can run the application.

  1. Start the Express server:

   node server.js


Copy after login
  1. Start the React frontend:

   npm start


Copy after login

Once both are running:

  • You can visit http://localhost:3000 to see the login page.
  • After logging in, the authentication token will be saved, and you'll be redirected to the dashboard.
  • If the token is valid, you stay logged in, otherwise, you will be redirected back to the login page.

Summary

This example shows how to integrate Pulsy with a React authentication system backed by an Express.js API. Pulsy helps you manage global state for authentication, including persistence of the authentication token and user data across sessions, making it a powerful and easy-to-use state management tool.

The above is the detailed content of Authentication with express js and react js unsing jwt. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template