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 [productssetProducts= 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", (reqres=> {
  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", (reqres=> {
  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 (reqres=> {
  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 (reqres=> {
  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 (reqres=> {
  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 (reqres=> {
  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 = (reqresnext=> {
  const token = req.header.authorization;
  if (token) {
    const onlyToken = token.slice(7token.length);
    jwt.verify(onlyToken, config.JWT_SECRET, (errdecode=> {
      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 = (reqresnext=> {
  if (req.user && req.user.isAdmin) {
    return next();
  }
  return res.status(401).send({ msg: "Admin token is not valid" });
};

export { getTokenisAuthisAdmin };

Post dữ liệu

Thực hiện trong server/routes/userRouter.js

router.post("/product"async (reqres=> {
  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 (reqres=> {
  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 (reqres=> {
  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