A full-stack application with JWT authentication using React + Tailwind CSS for the frontend and Express + PostgreSQL for the backend.
- User registration and login
- JWT token-based authentication with UUID user IDs
- Protected routes
- Password hashing with bcrypt
- Modern UI with Tailwind CSS
- React Context API for state management
- PostgreSQL with UUID primary keys
- React 18
- Vite
- Tailwind CSS
- React Router DOM
- Axios
- Node.js
- Express
- PostgreSQL
- JWT (jsonwebtoken)
- bcrypt
- dotenv
- Node.js (v18 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
First, make sure PostgreSQL is running and create a database:
# Login to PostgreSQL
psql -U postgres
# Create database
CREATE DATABASE supertictactoe;
# Exit
\q# Navigate to server directory
cd server
# Install dependencies
npm install
# The .env file is already configured with:
# - POSTGRES_URL=postgresql://harsh:password@localhost:5432/supertictactoe
# - JWT_SECRET (change this in production!)
# - PORT=5000
# Start the server
npm run devThe server will run on http://localhost:5000 and automatically create the users table.
Open a new terminal:
# Navigate to client directory
cd client
# Install dependencies
npm install
# Start the development server
npm run devThe frontend will run on http://localhost:3000
-
POST /api/auth/register- Register a new user{ "username": "johndoe", "email": "john@example.com", "password": "password123" } -
POST /api/auth/login- Login user{ "email": "john@example.com", "password": "password123" } -
GET /api/auth/me- Get current user (Protected)- Requires:
Authorization: Bearer <token>header
- Requires:
-
GET /api/health- Health check endpoint
.
├── client/ # React frontend
│ ├── src/
│ │ ├── components/ # Reusable components
│ │ ├── context/ # React Context (Auth)
│ │ ├── pages/ # Page components
│ │ ├── App.jsx # Main app component
│ │ ├── main.jsx # Entry point
│ │ └── index.css # Tailwind imports
│ ├── package.json
│ ├── vite.config.js
│ └── tailwind.config.js
│
└── server/ # Express backend
├── middleware/ # Auth middleware
├── routes/ # API routes
├── database.js # PostgreSQL connection
├── server.js # Express app
├── .env # Environment variables
└── package.json
- Start both the backend and frontend servers
- Open
http://localhost:3000in your browser - Register a new account
- Login with your credentials
- Access the protected dashboard
- Important: Change the
JWT_SECRETin.envbefore deploying to production - Passwords are hashed using bcrypt with 10 salt rounds
- JWT tokens expire after 7 days
- All passwords must be at least 6 characters
- Email validation is enforced
- User IDs use UUID v4 for better security and uniqueness (non-sequential, harder to guess)
cd server
npm run dev # Uses nodemon for hot reloadingcd client
npm run dev # Vite provides hot module replacementFrontend:
cd client
npm run build
npm run preview # Preview production buildPOSTGRES_URL=postgresql://username:password@localhost:5432/database_name
JWT_SECRET=your-secret-key
PORT=5000
NODE_ENV=developmentMIT