You’ve built a secure Django API—now let’s use it. Learn how to build a React frontend that handles Token authentication and communicates with your 4 custom endpoints.
The Architecture: How they Talk
Because React and Django are two separate "islands," they communicate via HTTP requests. React sends a request (with a Token "key"), and Django sends back JSON data.
Step 1: The Django "CORS" Fix
By default, browsers block React (Port 3000) from talking to Django (Port 8000) for security.
You must install django-cors-headers in your Django project:
# In your Django Terminal
pip install django-cors-headers
# In settings.py
INSTALLED_APPS = [..., 'corsheaders',]
MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', ...]
CORS_ALLOWED_ORIGINS = ["http://localhost:3000"]
Step 2: Initialize React & Bootstrap
Create your React app and install Axios (for API calls) and Bootstrap (for a clean UI):
npx create-react-app django-frontend
cd django-frontend
npm install axios bootstrap
Open src/index.js and add: import 'bootstrap/dist/css/bootstrap.min.css';
Step 3: The Critical Bootstrap Import
Installing Bootstrap isn't enough. You must tell React to load the CSS. Open src/main.jsx (Vite) or src/index.js (CRA) and add this line at the very top:
import 'bootstrap/dist/css/bootstrap.min.css';
Without this line, your buttons will look like plain blue links and your layout will be broken.
Step 4: The React "Controller" Code
Replace App.js with this logic. It maps exactly to the 4 URLs we built in previous posts:
import React, { useState } from 'react';
import axios from 'axios';
function App() {
const [token, setToken] = useState('');
const [response, setResponse] = useState(null);
const API_URL = "http://127.0.0.1:8000/api";
// Function to simplify headers
const getHeaders = () => ({ headers: { Authorization: `Token ${token}` } });
const handleAction = (method, endpoint, data = {}) => {
const config = (endpoint === '/public/' || endpoint === '/login/') ? {} : getHeaders();
axios({ method, url: `${API_URL}${endpoint}`, data, ...config })
.then(res => {
if(endpoint === '/login/') setToken(res.data.token);
if(endpoint === '/logout/') setToken('');
setResponse(res.data);
})
.catch(err => setResponse(err.response?.data || "Error Connecting"));
};
return (
<div className="container py-5">
<div className="card shadow border-0">
<div className="card-header bg-dark text-white text-center">
<h3>Django API Control Panel</h3>
</div>
<div className="card-body">
<div className="btn-group w-100 mb-4">
<button className="btn btn-outline-secondary" onClick={() => handleAction('get', '/public/')}>1. Public GET</button>
<button className="btn btn-primary" onClick={() => handleAction('post', '/login/', {username:'admin', password:'123'})}>2. Login</button>
<button className="btn btn-warning" onClick={() => handleAction('get', '/private/')}>3. Private GET</button>
<button className="btn btn-danger" onClick={() => handleAction('post', '/logout/')}>4. Logout</button>
</div>
{response && (
<div className="alert alert-light border">
<strong>Server Response:</strong>
<pre className="mt-2">{JSON.stringify(response, null, 2)}</pre>
</div>
)}
</div>
<div className="card-footer text-muted">
Active Token: <code>{token || "No Session"}</code>
</div>
</div>
</div>
);
}
export default App;
State vs. Persistence: Managing Authentication Tokens in React
In React, useState acts as the app's "short-term memory," allowing the UI to react instantly when a token is received from Django. However, because state is stored in the computer's RAM, it is completely wiped clean the moment a user refreshes their browser. To solve this, we use localStorage, which acts as a "long-term vault" that saves the token to the browser's hard drive. By combining both, we can save the token to the disk upon login and automatically pull it back into the React state when the app restarts. This ensures a seamless user experience where the session remains active even after the tab is closed or the page is reloaded.
Final Troubleshooting Checklist
- 403 Forbidden? Ensure you sent the header as
Token [key](with a space!). - Network Error? Make sure your Django server is actually running on port 8000.
- CORS Error? Double-check the
MIDDLEWAREorder in Django;CorsMiddlewaremust be at the very top.