Files
modstagram-back/middlewares/index.js
payacom 3f416a7a60 full
2026-08-31 20:45:41 +03:30

58 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const bodyParser = require('body-parser')
const formData = require('express-form-data')
const session = require('express-session')
const { RedisStore } = require('connect-redis')
const { getRedisClient, getRawClient } = require('../utils/redisClient')
const lastOnline = require('./lastOnline')
const SESSION_OPTIONS = {
secret: process.env.SESSION_SECRET || process.env.JWT_SECRET || 'change-me-in-production',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
},
}
// قبلاً MemoryStoreِ پیش‌فرضِ express-session بود — برای production مناسب نیست (نه
// بین چند اینستنس‌سرور مشترکه، نه محدودیتی داره). الان وقتی Redis وصله از یه store
// مشترک استفاده می‌شه. عین ratedLimiter (createRateLimiter.js): دو نمونه‌ی کاملاً
// جدا ساخته می‌شه و روی *هر* درخواست بر اساسِ آماده‌بودنِ فعلیِ Redis سوییچ می‌شه —
// نه اینکه همیشه به Redis وصل بشه و فقط منتظرِ خطا بمونه. اون روش (client خام،
// بدون چکِ آماده‌بودن) وقتی Redis اصلاً هیچ‌وقت در دسترس نبود (مثلاً یه دیپلویِ
// تازه که هنوز Redis روش ست نشده)، هر درخواست رو تا انقضای connectTimeout کند
// می‌کرد؛ این نسخه اون تأخیر رو صفر می‌کنه چون اصلاً منتظرِ Redis نمی‌مونه
const redisSession = session({
...SESSION_OPTIONS,
store: new RedisStore({ client: getRawClient(), prefix: 'sess:' }),
})
const memorySession = session(SESSION_OPTIONS)
// نکته: اگه Redis وسطِ یه session بیفته (بعد از ساخته‌شدن یه سشنِ Redis-محور)،
// سوییچ به memorySession یعنی اون سشنِ خاص موقتاً دیده نمی‌شه — قابل‌قبوله چون این
// اپ اصلی‌ترین احرازهویتش JWTه، نه سشن (req.session جای دیگه‌ای توی این کدبیس
// استفاده نمی‌شه)
function dispatchSession (req, res, next) {
const store = getRedisClient() ? redisSession : memorySession
store(req, res, (err) => {
if (err) {
// fallback نهایی برای همون ریسِ نادرِ «Redis درست وسطِ همین درخواست قطع شد» —
// به‌جای next(err) (که express-session پیش‌فرضش ۵۰۰-کردنِ کل درخواسته)، فقط
// لاگ می‌کنیم و بدون سشن ادامه می‌دیم
console.error('[session] store error — continuing without session:', err.message)
return next()
}
next()
})
}
module.exports = (app) => {
app.use(formData.parse())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(dispatchSession)
app.use(lastOnline)
}