full
This commit is contained in:
@@ -1,17 +1,57 @@
|
||||
const bodyParser = require('body-parser')
|
||||
const cors = require('cors')
|
||||
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(cors()) // develop
|
||||
app.use(formData.parse())
|
||||
app.use(bodyParser.json())
|
||||
app.use(bodyParser.urlencoded({ extended: true }))
|
||||
app.use(session({
|
||||
secret: 'your_secret_key', // کلید مخفی برای امنیت جلسات
|
||||
resave: false,
|
||||
saveUninitialized: false
|
||||
}))
|
||||
app.use(dispatchSession)
|
||||
app.use(lastOnline)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user