Nay mình chia sẻ với mọi người cách ta có thể Kết nối(Connect) MongoDB với Node.JS . Vừa qua mình có việc làm lại một dự án nhỏ, có Connect MongoDB + NodeJS+ Vue(kết hợp Vuex) quản lý trạng thái (state) của dữ liệu
Cũng lâu rồi mình không có dùng lại MongoDB , tìm tồi cài đặt nó làm mình rối cả lên kaka. Nhưng không sao, còn hơi thở thì ta sẽ tìm ra thôi mà kaka
# Install MongoDB in Windows 10
Việc đầu tiên là ta cài tìm và cài đặt MongoDB. Các bạn hãy vào đây và download về cài đặt nhé : https://www.mongodb.com/try/download/community
Sao khi bạn cài đặt xong bạn sẽ được giao như trên, bạn sẽ được một chuổi kết nối như thế này mongodb://localhost:27017 , Hãy bấm vào chữ "Connect" để tiếp tục ta tạo database
Việc còn lại là tạo project Nodejs và Connect MongoDB vào thôi
# Setup NodeJS Connect MongoDB
Tạo project Nodejs. Các bạn cần phải cài thư viện Node.js vào máy tính mình nhé
npm init
Okay các bạn có thể copy package,json của mình dùng để cài đặt cho lẹ và nhanh, còn không bạn cài đặt từng thư viện vào
{ "name": "nodejs-react", "version": "1.0.0", "description": "nodejs react", "main": "index.js", "scripts": { "start": "node index.js", "dev": "nodemon index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "nodejs", "react" ], "author": "hoanguyenit", "license": "ISC", "dependencies": { "bcryptjs": "^2.4.3", "body-parser": "^1.19.0", "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", "jsonwebtoken": "^8.5.1", "mongodb": "^6.2.0", "mongoose": "^6.0.9", "sqlite3": "^5.0.2", "uid": "^2.0.0" }, "devDependencies": { "nodemon": "^2.0.13" } }
Sao đó mở Command Line lên và chạy lệnh npm install
npm install
Vậy là bạn đã cài đặt toàn bộ thư viện như : jsonwebtoken, cors, mongodb, mongoose,... sao này dùng cái nào thì import vào file thôi
Sau khi đã có project Nodejs rồi, bạn tạo cho mình file index.js cùng cấp với project
const http = require("http"); const app = require("./app"); const server = http.createServer(app); const { API_PORT } = process.env; const port = process.env.PORT || API_PORT; // server listening server.listen(port, () => { console.log(`Server running on port ${port}`); });
Tiếp theo hãy tạo app.js như sau:
require("dotenv").config(); const express = require("express"); const jwt = require("jsonwebtoken"); const { MongoClient } = require('mongodb'); var cors = require('cors'); const router = express.Router(); const app = express(); app.use(cors()); app.use(express.json()); // Connection URL const url = 'mongodb://127.0.0.1:27017'; const client = new MongoClient(url); // Database Name const dbName = 'shopbanhang'; let connectDB; // Kết nối đến MongoDB async function connectToMongoDB() { try { await client.connect(); console.log('Connected to MongoDB'); // Lưu trữ đối tượng cơ sở dữ liệu để sử dụng toàn cục connectDB = client.db("shopbanhang"); } catch (error) { console.error('Error connecting to MongoDB:', error); } } connectToMongoDB().catch(console.dir); //lấy tất cả danh sách hang hoa router.get("/getItems", async (req, res) => { try { const collection = connectDB.collection("HangHoa"); // Sử dụng phương thức find() để lấy tất cả các documents trong collection const hanghoas = await collection.find({}).toArray(); // Log tất cả users res.status(200).json({"success":1,"ListsHangHoa":hanghoas}); } catch (error) { console.error('Error getting all hanghoas:', error); } }) app.use('/', router); module.exports = app;
Bên trên mình cần import thư viện mongodb
const { MongoClient } = require('mongodb');
Tiếp theo là lúc chúng ta gọi connect đến MongoDB
// Connection URL const url = 'mongodb://127.0.0.1:27017'; const client = new MongoClient(url); // Database Name const dbName = 'shopbanhang'; let connectDB; // Kết nối đến MongoDB async function connectToMongoDB() { try { await client.connect(); console.log('Connected to MongoDB'); // Lưu trữ đối tượng cơ sở dữ liệu để sử dụng toàn cục connectDB = client.db("shopbanhang"); } catch (error) { console.error('Error connecting to MongoDB:', error); } } connectToMongoDB().catch(console.dir);
Bạn thấy mình dùng địa chỉ 127.0.0.1, thay vì là localhost đúng không. Trường hợp bạn dùng connect chuỗi mongodb://localhost:27017 không được, thì hãy dùng địa chỉ ip nhé : mongodb://127.0.0.1:27017
Vậy là xong, Các bạn viết các câu lệnh thêm, sửa , delete, thử nhé
Okay giờ chúng ta có thể chạy nó bằng câu lệnh sau:
npm run dev //or node index.js
Dưới đây mã code mình dùng Nodejs+MongoDB. cùng với kết hợp với Json Web Token các bạn có thể xem thêm bài viết này -> : JWT(Json Web Token) In Node.Js
Các bạn có thể tham thao thêm app.js :
require("dotenv").config(); const express = require("express"); const jwt = require("jsonwebtoken"); const { MongoClient } = require('mongodb'); var cors = require('cors'); const router = express.Router(); const app = express(); app.use(cors()); app.use(express.json()); // Connection URL const url = 'mongodb://127.0.0.1:27017'; const client = new MongoClient(url); // Database Name const dbName = 'shopbanhang'; let connectDB; // Kết nối đến MongoDB async function connectToMongoDB() { try { await client.connect(); console.log('Connected to MongoDB'); // Lưu trữ đối tượng cơ sở dữ liệu để sử dụng toàn cục connectDB = client.db("shopbanhang"); } catch (error) { console.error('Error connecting to MongoDB:', error); } } // async function run() { // try { // await client.connect(); // const database = client.db(dbName); // // const collection = database.collection("users"); // // const users = await collection.find({}).toArray(); // // Log tất cả users // console.log(users); // } finally { // // Đảm bảo rằng client sẽ đóng khi kết thúc hoặc có lỗi // await client.close(); // } // } connectToMongoDB().catch(console.dir); //xây dụng các chức năng lấy dữ liệu //lấy tất cả danh sách hang hoa router.get("/getItems", async (req, res) => { try { const collection = connectDB.collection("HangHoa"); // Sử dụng phương thức find() để lấy tất cả các documents trong collection const hanghoas = await collection.find({}).toArray(); // Log tất cả users res.status(200).json({"success":1,"ListsHangHoa":hanghoas}); } catch (error) { console.error('Error getting all hanghoas:', error); } }) //lấy tất cả danh sách hang hoa theo ID router.get("/getItems/:id", async (req, res) => { try { const collection = connectDB.collection("HangHoa"); let MSHH = { "MSHH": parseInt(req.params.id) }; let hanghoa = await collection.findOne(MSHH); if (hanghoa) { res.status(200).json({ "success": 1, "hanghoa": hanghoa }); } else { res.status(200).json({ "success": 0, "messsage": "Sản phẩm không tồn tại", "id": req.params.id }); } } catch (error) { console.error('Error getting hanghoa:', error); res.status(500).json({ "success": 0, "message": "Lỗi server" }); } }) // Register khách hàng router.post("/register/khachhang", async (req, res) => { // Our register logic starts here try { // Get user input const { HoTenKH, Password, SoDienThoai, DiaChi } = req.body; const collection = connectDB.collection("KhachHang"); // Kiểm tra xem khách hàng đã tồn tại chưa const existingCustomer = await collection.findOne({ SoDienThoai }); if (existingCustomer) { return res.status(400).json({ message: 'Khách hàng đã tồn tại.' }); } const MSKH = `MSKH${Date.now()}`; // Tạo một bản ghi mới const newCustomer = { MSKH, HoTenKH, Password, SoDienThoai, DiaChi, }; // Chèn bản ghi mới vào cơ sở dữ liệu await collection.insertOne(newCustomer); res.status(201).json({ message: 'Đăng ký thành công.' }); /* save user to databse */ } catch (err) { console.log(err); } }); // Register nhân viên router.post("/register/nhanvien", async (req, res) => { // Our register logic starts here try { // Get user input const { HoTenNV, Password, SoDienThoai, DiaChi,ChucVu } = req.body; const collection = connectDB.collection("NhanVien"); // Kiểm tra xem khách hàng đã tồn tại chưa const existingCustomer = await collection.findOne({ SoDienThoai }); if (existingCustomer) { return res.status(400).json({ message: 'Nhân viên đã tồn tại.' }); } const MSNV = `MSNV${Date.now()}`; // Tạo một bản ghi mới const newCustomer = { MSNV, HoTenNV, Password, SoDienThoai, ChucVu, DiaChi, }; // Chèn bản ghi mới vào cơ sở dữ liệu await collection.insertOne(newCustomer); res.status(201).json({ message: 'Đăng ký thành công.' }); /* save user to databse */ } catch (err) { console.log(err); } }); // Login (nhân viên hoặc khách hàng or Nhaan vieen, position:1 -> nhanvien, position:0->khachhang router.post("/login", async (req, res) => { const { msnv, password,position } = req.body; if (!(msnv && password)) { res.status(400).send("All input is required"); }else{ try { let collection; let user; if(position>0){ collection = connectDB.collection("NhanVien"); user = await collection.findOne({ MSNV: msnv, Password: password, }); } else{ collection = connectDB.collection("KhachHang"); user = await collection.findOne({ MSKH: msnv, Password: password, }); } // Tìm một nhân viên với MSNV và password tương ứng if (user) { var data; if(position>0){ data={ "MSNV":user.MSNV, "HoTenNV":user.HoTenNV, "ChucVu":user.ChucVu, "DiaChi":user.DiaChi, "SoDienThoai":user.SoDienThoai } } else{ data={ "MSKH":user.MSKH, "HoTenKH":user.HoTenKH, "DiaChi":user.DiaChi, "SoDienThoai":user.SoDienThoai } } var token = jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60*60), user: data }, process.env.ACCESS_TOKEN_SECRET); var refresh_token = jwt.sign({ exp: Math.floor(Date.now() / 1000) + (24*60*60), user: data }, process.env.REFRESH_TOKEN_SECRET); try { let result; if(position>0){ result = await collection.updateOne( { MSNV: msnv }, { $set: { token: token, refresh_token: refresh_token } } ); } else{ result = await collection.updateOne( { MSKH: msnv }, { $set: { token: token, refresh_token: refresh_token } } ); } if (result.modifiedCount > 0) { res.status(200).json({"success":1,"message":"Login successful",user:result,"token":token,"refresh_token":refresh_token}); } else { res.status(200).json({"success":1,"message":"Không thể update token",user:data,"token":token,"refresh_token":refresh_token}); } } catch (error) { console.error('Error during update:', error); } } else { res.status(200).json({"success":-1,"message": "Login failed. Invalid MSNV or password."}); } } catch (error) { res.status(200).json({"success":-1,"message": "error table in database"}); } } }); /** * Lấy mã token mới sử dụng Refresh token * POST /refresh_token */ router.post('/refresh_token', async (req, res) => { try { const { refreshToken, position } = req.body; // Kiểm tra refreshToken có tồn tại if (!refreshToken) { return res.status(400).json({ success: 0, message: "Refresh token is required" }); } // Kiểm tra refresh token có hợp lệ let collection; if(position>0) { collection = connectDB.collection("NhanVien"); }else{ collection = connectDB.collection("KhachHang"); } let result = await collection.findOne({ refresh_token: refreshToken }); if (result && result.refresh_token) { let row_refresh_token = result.refresh_token; var decoded = jwt.verify(row_refresh_token, process.env.REFRESH_TOKEN_SECRET); var token = jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60*60), user: decoded.user }, process.env.ACCESS_TOKEN_SECRET); res.status(200).json({"success":1,"data":decoded,"token":token,"refresh_token":row_refresh_token}); } else { res.status(404).json({ success: 0, message: "Refresh token not found" }); } } catch (error) { console.error('Error refreshing token:', error); res.status(500).json({ success: 0, message: "Internal Server Error" }); } }); /** * Middleware xác thực người dùng dựa vào mã token * @param {*} req * @param {*} res * @param {*} next */ const TokenCheckMiddleware = async (req, res, next) => { // Lấy thông tin mã token được đính kèm trong request const token = req.body.token || req.query.token || req.headers['x-access-token']; // decode token if (token) { // Xác thực mã token và kiểm tra thời gian hết hạn của mã try { var decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); // Lưu thông tin giã mã được vào đối tượng req, dùng cho các xử lý ở sau req.decoded = decoded; next(); } catch (err) { // Giải mã gặp lỗi: Không đúng, hết hạn... console.error(err); return res.status(401).json({ message: 'Unauthorized access.', }); } } else { // Không tìm thấy token trong request return res.status(403).send({ message: 'No token provided.', }); } } router.post("/get-info-nhanvien",TokenCheckMiddleware, (req, res) => { return res.status(200).json({"token":req.decoded}) }); router.use(TokenCheckMiddleware) router.post("/welcome", (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); } try { var decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); res.status(200).send(decoded.user); } catch (err) { return res.status(401).send("Invalid Token"); } }); /* cập nhật khách khàng */ router.post("/update/khachhang", async (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); } try { const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); // Kiểm tra thời hạn của token const currentTime = Math.floor(Date.now() / 1000); // Thời gian hiện tại tính bằng giây if (decoded.exp && decoded.exp < currentTime) { // Token đã hết hạn, bạn có thể xử lý refresh token ở đây return res.status(401).send("Token has expired, please log in again"); // Ví dụ: // const refreshToken = await RefreshToken.findOne({ userId: decoded.user.id }); /* if (refreshToken) { // Tạo mới access token và gửi về client const newAccessToken = jwt.sign({ user: decoded.user }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '15m' }); res.status(200).json({ accessToken: newAccessToken }); } else { // Không tìm thấy refresh token, đòi hỏi người dùng đăng nhập lại res.status(401).send("Token has expired, please log in again"); } */ } else { // Token còn hạn, tiếp tục xử lý res.status(200).json(decoded.user); } } catch (err) { // Lỗi xác thực token return res.status(401).send("Invalid Token"); } }) //dat don hang router.post("/dathang/check-out", async (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); }else{ try { const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); const data = decoded.user const {HoTenKH, SoDienThoai, DiaChi,MSKH,carts} = req.body; // Lấy ngày đặt hàng hiện tại const ngayDatHang = new Date().toISOString().split('T')[0]; // Lấy ngày giao hàng sau 3 ngày const ngayGiaoHang = new Date(); ngayGiaoHang.setDate(ngayGiaoHang.getDate() + 2); const ngayGiaoHangFormatted = ngayGiaoHang.toISOString().split('T')[0]; const SoDonHang =`${Date.now()}`; const newDonhang = { "SoDonDH": SoDonHang, "MSKH":data.MSKH, "MSNV":"1233", "NgayDH":ngayDatHang, "NgayGH":ngayGiaoHangFormatted, "TrangThaiDH":0 } const collection = connectDB.collection("DatHang"); // Chèn bản ghi mới vào cơ sở dữ liệu const result = await collection.insertOne(newDonhang); if(result){ const cartsWithSoDonHang = carts.map(cart => ({ ...cart, MSDH: SoDonHang })); //thêm danh sách chi tiết đơn hàng const collection = connectDB.collection("ChiTietDatHang"); // Chèn nhiều bản ghi mới vào cơ sở dữ liệu const result = await collection.insertMany(cartsWithSoDonHang); res.status(200).json({"success":1,"donhang":cartsWithSoDonHang,"message":"Đặt hàng thành công"}); } } catch (error) { res.status(200).json({"success":-1,"message":"Token has expired, please log in again"}); } } }) //check don hang dat don hang router.get("/check/dathang/:id", async (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); }else{ try { //const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); //const data = decoded.user const collection = connectDB.collection("DatHang"); const result = await collection.findOne({ SoDonDH: req.params.id, }); if(!result) res.status(200).json({"success":0,"message":"Không tồn tại đơn hàng"}); let TrangThaiDH = result.TrangThaiDH; if(result.TrangThaiDH == 0){ TrangThaiDH = 1; } let kq = await collection.updateOne( { SoDonDH: req.params.id }, { $set: { TrangThaiDH:TrangThaiDH} } ); res.status(200).json({"success":1,"donhang":kq,"message":"Đã cập nhật đơn hàng"}); } catch (error) { res.status(200).json({"success":-1,"message":"Token has expired, please log in again"}); } } }); //lấy tất cả danh sách nhân viên router.get("/users", async (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); }else{ try { const collection = connectDB.collection("NhanVien"); // Sử dụng phương thức find() để lấy tất cả các documents trong collection const users = await collection.find({}).toArray(); // Log tất cả users console.log(users); res.status(200).json({"success":1,"ListNhanVien":users}); } catch (error) { console.error('Error getting all users:', error); } } }) //lấy tất cả danh sách đơn hàng router.get("/getdathangs", async (req, res) => { const token = req.body.token || req.query.token || req.headers["x-access-token"]; if (!token) { return res.status(403).send("A token is required for authentication"); }else{ try { const collection = connectDB.collection("DatHang"); // Sử dụng phương thức find() để lấy tất cả các documents trong collection const dathangs = await collection.find({}).toArray(); let dsdonhang = []; for (const item of dathangs){ const collection = connectDB.collection("ChiTietDatHang"); const chitietdathang = await collection.find({ MSDH: item.SoDonDH, }).toArray(); let chitiet = []; for(const hang of chitietdathang){ let MSHH = hang.MSHH const collection = connectDB.collection("HangHoa"); const hanghoa = await collection.findOne({ MSHH: MSHH, }); hang.TenHH = hanghoa.TenHH; chitiet.push(hang); } dsdonhang.push({ "SoDonDH":item.SoDonDH, "NgayDH":item.NgayDH, "NgayGH":item.NgayGH, "TrangThaiDH":item.TrangThaiDH, "ChiTietDatHang":chitiet }) } res.status(200).json({"success":1,"ListDatHang":dsdonhang}); } catch (error) { console.error('Error getting all users:', error); } } }) app.use('/', router); module.exports = app;
Hẹn mọi người bài viết sau!