ο»Ώ# MERN-tailwind-daisyui-react-query-TwitterClone
Purpose: Used for generating and verifying tokens for authentication.
Why Use It: Securely transmit data between parties as a JSON object using a token. Useful for user authentication and authorization.
Common Usage:
Purpose: Used for hashing passwords securely.
Why Use It: Password hashing ensures that even if your database is compromised, user passwords remain safe.
Common Usage:
Purpose: A cloud-based media management service.
Why Use It: Efficiently store, optimize, and manage images, videos, and other media. Ideal for image uploads in web apps.
Common Usage:
Example:
import cloudinary from 'cloudinary';
cloudinary.config({
cloud_name: 'your-cloud-name',
api_key: 'your-api-key',
api_secret: 'your-api-secret',
});
const result = await cloudinary.uploader.upload('path/to/image.jpg');
console.log(result.url); // URL of uploaded image
Purpose: Middleware to parse cookies in a Node.js application.
Why Use It: Useful for handling cookies sent from the client, often for storing authentication tokens or session data.
Common Usage:
Example:
import express from 'express';
import cookieParser from 'cookie-parser';
const app = express();
app.use(cookieParser());
app.get('/', (req, res) => {
console.log(req.cookies); // Access cookies from request
res.cookie('token', '123456', { httpOnly: true });
res.send('Cookie set!');
});
app.listen(3000, () => console.log('Server running on port 3000'));
Some Features:
mkdir react-twitter-clone
npm init -y
npm install express dotenv mongoose nodemon jsonwebtoken bcryptjs
put the .env file here
mkdir backend
cd backend
echo ""> server.js
add "type" :"module", in package.json so can use import not require and export default not models.export
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon backend/server.js"
},
so can run the backend: npm run dev
https://v3.tailwindcss.com/docs/guides/vite
npm create vite@latest frontend -- --template react
cd frontend
npm install
Install tailwindv3 and daisy UI: https://v3.tailwindcss.com/docs/installation
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p
config tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
copy the following to src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Install daisyUI as a Tailwind plugin https://daisyui.com/docs/install/ daisyui won't work for theme
npm install @tanstack/react-query react-icons react-router-dom
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
MONGO_URI=""
PORT=5000
NODE_ENV="development"
JWT_SECRET=""
JWT_EXPIRE=""
CLOUDINARY_CLOUD_NAME=""
CLOUDINARY_API_KEY=""
CLOUDINARY_API_SECRET=""
import jwt from 'jsonwebtoken';
const secretKey = 'yourSecretKey';
const payload = { userId: 123 };
// Generate a JWT token
const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });
// Verify token
const decoded = jwt.verify(token, secretKey);
console.log(decoded); // { userId: 123, iat: ..., exp: ... }
JWT (JSON Web Token) uses signing rather than traditional hashing or encryption.
JWT consists of three parts:
The structure looks like this:
HEADER.PAYLOAD.SIGNATURE
Each section is Base64 URL encoded for easy transport.
JWT does not encrypt data by default.
JWT uses signing, not hashing for integrity
Hereβs the step-by-step process using HS256 (Symmetric signing):
Create Header
{
"alg": "HS256",
"typ": "JWT"
}
Create Payload
{
"userId": 123,
"role": "admin",
"exp": 1713800000
}
exp
is an expiration timestamp.
Sign the Token
HMACSHA256(Base64UrlEncode(header) + "." + Base64UrlEncode(payload), secret)
userId
and role
, which is generally safe.π Best Practices to Keep JWTs Secure:
exp
) to limit the tokenβs validity.jwt.verify()
before granting access.Purpose: Used for hashing passwords securely.
Why Use It: Password hashing ensures that even if your database is compromised, user passwords remain safe.
Common Usage:
Example:
```javascript
import bcrypt from 'bcrypt';
const saltRounds = 10; const password = 'userPassword123';
// Hashing a password const hashedPassword = await bcrypt.hash(password, saltRounds);
// Compare password const isMatch = await bcrypt.compare(password, hashedPassword); console.log(isMatch); // true if matched