Cấu hình server cho Backend trong dự án
Khởi tạo server
Để khởi tạo một server backend trước tiên ta sẽ khởi tạo Node express thông qua npm
npm init
npm install express --save
npm install @babel/cli @babel/core @babel/node @babel/preset-env nodemon --save-dev
Cài đặt cấu hình file .babelrc
{"presets": [["@babel/preset-env"]]}
Set Proxy cho package.json của client
"name": "client",
"proxy": "http://127.0.0.1:5000",
"version": "0.1.0",
"private": true,
Fetching Data từ server qua client
const [products, setProducts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const { data } = await axios.get("api/products");
setProducts(data);
};
fetchData();
}, []);
Lấy dữ liệu từ server
Truy cập vào server/index.js
app.get("/api/products", (req, res) => {
res.send(data.products);
});
Truy cập vào từng danh mục
Sau khi lấy được params từ client thì sử dụng phương thức GET từ client kết nối tới server sau đó ta sẽ viết như sau trên server/index.js
app.get("/api/product/:id", (req, res) => {
const productId = req.params.id;
const product = data.products.find((x) => x._id === productId);
if (product) {
res.send(product);
} else {
res.status(404).send({ msg: "Product Not Found!" });
}
});
Khởi tạo user
Sau khi cấu hình xong server/models/userModal ở dưới xong thì ta khởi tạo server/routes/userRouter
import User from "../models/userModel";
router.get("/createadmin", async (req, res) => {
try {
const user = new User({
name: "giakhanhlk",
email: "giakhanhlk@gmail.com",
password: "561250",
isAdmin: true,
});
const newUser = await user.save();
res.send(newUser);
} catch (error) {
res.send({ message: error.message });
}
});
Kết nối mongoose
cài đặt server/config.js
export default {
MONGODB_URL: process.env.MONGODB_URL || "mongodb://localhost/amazona",
};
Tạo routes/userRoute.js
import express from "express";
import User from "../models/userModel";
const router = express.Router();
router.get("/createadmin", async (req, res) => {
try {
const user = new User({
name: "giakhanhlk",
email: "giakhanhlk@gmail.con",
password: "561250",
isAdmin: true,
});
const newUser = await user.save();
res.send(newUser);
} catch (error) {
res.send({ msg: error.message });
}
});
export default router;
install các package dotenv, mongoose
import dotenv from "dotenv";
import express from "express";
import mongoose from "mongoose";
import config from "./config";
import data from "./data";
import userRoute from "./routes/userRoute";
Cấu hình cho server/index.js
dotenv.config();
const mongodbUrl = config.MONGODB_URL;
mongoose
.connect(mongodbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.catch((error) => console.log(error.reason));
app.use("/api/users", userRoute);
Cấu hình cho server/models/userModal
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: { type: Boolean, required: true, default: false },
});
const userModel = mongoose.model("User", userSchema);
export default userModel;
JWT (Authentication)
Trước tiên ta sẽ khởi tạo POST request cho server
import express from "express";
import User from "../models/userModel";
import { getToken } from "../utils";
router.post("/signin", async (req, res) => {
const signinUser = await User.findOne({
email: req.body.email,
password: req.body.password,
});
if (signinUser) {
res.send({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdmin,
token: getToken(signinUser),
});
} else {
res.status(401).send({ message: "Invalid Email or Password." });
}
});
Thêm biến môi trường .env
MONGODB_URL=mongodb://localhost/amazona
JWT_SECRET=4kajc9Wa6Clve
Cấu hình server/config
export default {
MONGODB_URL: process.env.MONGODB_URL || "mongodb://localhost/amazona",
JWT_SECRET: process.env.JWT_SECRET || "4kajc9Wa6Clve",
};
Khởi tạo server/utils.js để thực hiện getToken nếu cần
import jwt from "jsonwebtoken";
import config from "./config";
const getToken = (user) => {
return jwt.sign(user, config.JWT_SECRET, {
expiresIn: "48h",
});
};
export { getToken };
hoặc cụ thể hơn
import jwt from "jsonwebtoken";
import config from "./config";
const getToken = (user) => {
return jwt.sign(
{
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
},
config.JWT_SECRET,
{
expiresIn: "48h",
}
);
};
export { getToken };
Để sử dụng được req.body thì ta phải set package body-parser
import bodyParser from "body-parser";
app.use(bodyParser.json());
Trường hợp Register
router.post("/register", async (req, res) => {
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
});
const newUser = user.save();
if (newUser) {
res.send({
_id: newUser.id,
name: newUser.name,
email: newUser.email,
isAdmin: newUser.isAdmin,
token: getToken(newUser),
});
} else {
res.status(401).send({ message: "Invalid User Data." });
}
});
Xác thực
Thực hiện trong server/utils
import jwt from "jsonwebtoken";
const isAuth = (req, res, next) => {
const token = req.header.authorization;
if (token) {
const onlyToken = token.slice(7, token.length);
jwt.verify(onlyToken, config.JWT_SECRET, (err, decode) => {
if (err) {
return res.status(401).send({ msg: "Invalid Token" });
}
req.user = token;
next();
return;
});
}
return res.status(401).send({ msg: "Token is not supplied" });
};
const isAdmin = (req, res, next) => {
if (req.user && req.user.isAdmin) {
return next();
}
return res.status(401).send({ msg: "Admin token is not valid" });
};
export { getToken, isAuth, isAdmin };
Post dữ liệu
Thực hiện trong server/routes/userRouter.js
router.post("/product", async (req, res) => {
const product = new Product({
name: req.body.name,
price: req.body.price,
image: req.body.image,
brand: req.body.brand,
category: req.body.category,
countInStock: req.body.countInStock,
description: req.body.description,
rating: req.body.rating,
numReviews: req.body.numReviews,
});
const newProduct = await product.save();
if (newProduct) {
res.status(201).send({ message: "New Product Created!", data: newProduct });
}
return res.status(500).send({ message: "Error" });
});
Thay đổi dữ liệu
router.put("/:id", isAuth, isAdmin, async (req, res) => {
const productId = req.params.id;
const product = await Product.findById(productId);
if (product) {
product.name = req.body.name;
product.price = req.body.price;
product.image = req.body.image;
product.brand = req.body.brand;
product.category = req.body.category;
product.countInStock = req.body.countInStock;
product.description = req.body.description;
const updatedProduct = await product.save();
if (updatedProduct) {
return res
.status(200)
.send({ message: "Product Updated", data: updatedProduct });
}
}
return res.status(500).send({ message: " Error in Updating Product." });
});
Xóa dữ liệu
router.delete("/:id", isAuth, isAdmin, async (req, res) => {
const deletedProduct = await Product.findById(req.params.id);
if (deletedProduct) {
await deletedProduct.remove();
res.send({ message: "Product Deleted" });
} else {
res.send("Error in Deletion.");
}
});
Nhận xét