Nội dung bài viết
Video học lập trình mỗi ngày
Nếu bạn đang xây dựng một ứng dụng web với Node.js và Express thì đa số bạn đã làm việc với user session trong ứng dụng của mình. Hãy nhìn lại bài viết "Ví dụ về NodeJS Session sử dụng Express Session" ở đó thoạt nhìn mọi chuyện rất dễ dàng, nhưng gần đây có nhiều người vấp phải lỗi sau:
"Warning: connect.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process."
và sau khi khám phá và tìm hiểu tôi được biết với cách triển khai session như trước khi sẽ có vấn đề. Giờ tìm hiểu xem một chút.
express-session là gì?
Thông thường chúng ta sẽ thực hiện npm install express-session
và add đoạn code này vào app.js
const express = require('express'), app = express(), session = require('express-session'); app.use(session({ secret: process.env.SECRET_KEY, resave: false, saveUninitialized: true }));
Bây giờ điều này thật tuyệt nhưng khi triển khai mã này vào môi trường product ứng dụng web của bạn sẽ bắt đầu rò rỉ bộ nhớ và gặp phải các vấn đề về hiệu suất. Điều này được tìm thấy ở file index.js
trong express-session (kể từ phiên bản phát hành 1.15.6): Hình ảnh
Điều đó có vẻ rằng? Bởi vì express-session theo mặc định sử dụng triển khai MemoryStore chỉ được thiết kế cho môi trường product. Nó không thể mở rộng tốt ngoài một quy trình duy nhất và sẽ làm cho ứng dụng của bạn chậm hơn là điều được đoán trước.
Không nên lưu trữ session trên Cookie
Đương nhiên rồi, càng hạn chế càng tốt. Ai biết người dùng đang làm gì với cookie ngay trên trang của họ có chứ. Thay vì lưu trữ thông tin lớn và thay đổi liên tục qua cookie trong trình duyệt của người dùng, chỉ một số nhận dạng duy nhất được lưu trữ ở phía máy khách được gọi là Session ID. Session ID này được chuyển đến máy chủ web mỗi khi trình duyệt đưa ra yêu cầu HTTP. Vậy có cách nào không, CÓ.
Session store mongoose
May mắn thay tôi đã tìm một liên kết github giúp tôi giải quyết được bài toán này. Nó khá hay đó là sử dụng package connect-mongo
hay xem tôi viết lại như thế nào?
app.use (session ( secret: 'SECRET KEY', resave: false, saveUninitialized: true, store: new MongoStore ({ url: 'mongodb: // localhost: 27017 / test-app', // URL MONGODB CỦA BẠN ttl: 14 * 24 * 60 * 60, autoRemove: 'native' }) ))
Với ttl
là thời gian hết hạn của một session. Đơn giản vậy thôi. Bây giờ, khi tôi đăng nhập vào Mongo Atlas và xem cơ sở dữ liệu của dự án của mình, tôi có thể thấy dữ liệu session cũng được lưu trữ ở đây!
Đối với một ứng dụng đơn giản, điều này thật tuyệt vời đối với tôi. Qua tốt, bạn có thể xem code full dưới đây:
const express = require('express'); const session = require('express-session'); const MongoStore = require('connect-mongo')(session); const app = express(); app.use(session({ secret: 'SECRET KEY', resave: false, saveUninitialized: true, store: new MongoStore({ url: 'mongodb://localhost:27017/test-app', ttl: 14 * 24 * 60 * 60, autoRemove: 'native' }) })); app.get('/', (req,res,next) => { req.session.user = { uuid: '12234-2345-2323423' } req.session.save(err => { if(err){ console.log(err); } else { res.send(req.session.user) } }); }) app.get('/end', (req,res,next) => { req.session.destroy(err => { if(err){ console.log(err); } else { res.send('Session is destroyed') } }); }) app.listen(4000, () => { console.log("App listening on port 4000") })
Khuyến khích đọc thêm:
https://meghagarwal.medium.com/storing-sessions-with-connect-mongo-in-mongodb-64d74e3bbd9c
https://dev.to/monicamakes/saving-session-data-with-connect-mongo-148b