1. Kirish
Xizmatni rivojlantirayotganda, ekranni amalga oshirishdan ko'ra, shundan keyin o'ylashga ko'proq vaqt sarflanilishi mumkin.
So'nggi paytlarda sayyohlik joylari kontent xizmatining sharh funksiyasini ishlab chiqishda bunday tajribani boshdan kechirdim.
Sharh funksiyasi foydalanuvchilarga bevosita sharh yozish va fotosurat joylashtirish imkonini beruvchi funksiyadir.
Funksiya o'zida nisbatan oddiy ko'rinadi. Foydalanuvchi sharh mazmunini kiritganda va rasmni yuklaganda, bu serverga saqlanadi va saqlangan ma'lumotlar yana ekranda ko'rsatiladi.
Dastlab sharhlarning to'g'ri ro'yxatga olinishi va ko'rilishi uchun e'tibor qaratdim. Ammo funksiya amalga oshirilgandan so'ng, ishga tushirish muhiti asosida yana bir marta ko'zdan kechirsam, kutganimdan ko'ra ko'proq savollar paydo bo'ldi.
-
Foydalanuvchi kutilmagan matn kiritganda nima bo'ladi?
-
HTML teglar yoki skript ko'rinishidagi kirish saqlansa, nima bo'ladi?
-
Rasmlar o'rniga fayl yuklaganda, bu rasm sifatida qanday qabul qilinadi?
-
Sharhni tuzatish jarayonida fayl ma'lumotlari va haqiqiy saqlangan ma'lumotlar bir-biridan farq qilsagina, nima bo'ladi?
Ishlab chiqarish muhitida muammo ko'rinmagan funksiya, ishga joylashish nuqtai nazaridan yana bir bor qaralganda, to'ldirilishi kerak bo'lgan jihatlar juda ko'p ekan.
Ushbu maqolada sharh funksiyasini yaxshilash jarayonida qo'llagankirish ma'lumotlarini tekshirish, rasm yuklashni tekshirish va ma'lumotlar to'g'riligi boshqarish tajribamiznibo'lishmoqchiman.
2. Ishlab chiqarish muhitida topilgan muammolar
Qaytish funksiyasi foydalanuvchilarga to'g'ridan-to'g'ri kontent yaratish imkonini beruvchi asosiy funksiyalardan biridir.
Boshqaruvchi ekrani bilan farqlanib, foydalanuvchilar qaysi qiymatlarni kiritishlarini oldindan taxmin qilish qiyin va dasturchi xohlamagan tarzda funksiyani ishlatishi mumkin.
Ishlash muhitini asosiy olgan holda quyidagi muammolarni topdim.
Xususan, sharh funksiyasi foydalanuvchilarning to'g'ridan-to'g'ri kiritadigan maydoni bo'lgani uchun, normal foydalanish senariyalaridan tashqari Kutilmagan kirish va istisno holatlarini ham hisobga olishqilishingiz kerak edi.
|
qismlangan |
Topilgan muammo |
ta'sir |
|---|---|---|
|
matn kiritish |
Xuddi shu ma'noga ega bo'lgan satr turli shakllarda saqlanishi mumkin |
Ma'lumotlar sifatining pasayishi |
|
Foydalanuvchi kiritishi |
HTML teg va skript shaklida kirish mumkin |
Xavfsizlik va operatsion xavflar |
|
Fayl yuklash |
MIME turidan foydalanib rasm ekanligini aniqlash |
Noto'g'ri fayl yuklash imkoniyati |
|
Rasmni tahrirlash |
Fayl ma'lumotlari va ma'lumotlar ma'lumotlari mos kelmasligi mumkin |
Ma'lumotlar muvofiqligi muammosi |
3. Matn kiritish qiymatlarini tasdiqlashni qo'llash
Birinchi o'zgartirilgan qism sharh matni va yozuvchi nomiga kiritish qiymatlari bilan bog'liq edi.
Dastlab foydalanuvchi kiritgan satrlarni shunday saqlab qo'yayotgan edik.
Lekin bir xil ma'noga ega bo'lgan satrlar kiritish uslubiga qarab turlicha saqlanishi mumkinligi ko'zga tashlandi.
Namuna sifatidato'liq kengaytirilgan belgilar va yarim kengaytirilgan belgilarfoydalanuvchi nuqtai nazaridan o'xshash ko'rinadi, lekin tizimda turli xil ma'lumotlar sifatida qabul qilinadi.
Bunday ma'lumotlar to'planganda qidiruv yoki ma'lumotlarni boshqarish jarayonida kutmagan muammolar yuzaga kelishi mumkin.
Buni hal qilish uchun saqlashdan oldin Matnni normalizatsiya jarayoniqo'shildi.
String normalized = Normalizer.normalize(value, Normalizer.Form.NFKC).trim();
if (normalized.indexOf('<') >= 0 || normalized.indexOf('>') >= 0) {
throw new IllegalArgumentException("Review text cannot contain angle brackets.");
}
NFKC(Normalizatsiya Shakl Muvofiqlik Kompozitsiyasi)dan foydalanib, matnni normalizatsiya qildik va <, > belgilarini o'z ichiga olgan hollarda saqlashni cheklashni o'zgartirdik.
Dastlab, jinsiy mazmunli iboralar yoki keraksiz teglarni kiritishni oldini olish maqsadida ko'p bo'lgan.
Biroq, tekshirish davomida HTML teglar yoki skript shaklidagi kiritish saqlanish ehtimolini ham hisobga olishimiz kerak edi.
Hozirgi xizmat tuzilmasida darhol muammo paydo bo'lmasa ham, saqlangan ma'lumotlar boshqa ekranlarda yoki funksiyalarda foydalanilsa,XSS(Cross Site Scripting) kabi muammolar yuzaga kelish ehtimolimavjud.
Natijada, bu tekshirish faqat oddiy maxsus belgilar cheklanishi emas, balki ma'lumotlar sifati va xizmat barqarorligini birgalikda hisobga olgan ish bo'ldi.
4. Frontend va backendning ikki marta tekshirish tuzilishi
Kiritilgan qiymatlarni tekshirishni qo'llagan holda yana bir savol kelib chiqdi: tekshirishni qayerda o'tkazish kerak?
Dastlab, backendda tekshirish yetarli deb o'yladim.
Biroq, foydalanuvchi saqlash tugmasini bosgandan keyin xato mavjudligini ko'rdi va foydalanuvchi tajribasi nuqtayi nazaridan bir oz ajirov bo'ldi.
Shuning uchun frontendda ham uning bilan bir xil tekshirish qoidalarini qo'lladim.
const hasUnsafeReviewText = (value: string) => {
const normalized = value.normalize('NFKC');
return normalized.includes('<') || normalized.includes('>');
};
Frontend da foydalanuvchi kiritgan zahoti tekshiriladi va tezkor javob beriladi, backend da esa saqlashdan oldin bir xil qoidalar bilan oxirgi tekshirish amalga oshiriladi.
Har bir sohaning roli quyidagilardir.
|
qism |
rol |
|---|---|
|
Frontend |
Kirishda darhol tasdiqlash va foydalanuvchi fikr-mulohazasi taqdim etish |
|
backend |
Saqlashdan oldin oxirgi tekshiruv va ma'lumotlarni saqlash |
Ushbu tuzilmani qoʻllaganimizdan soʻng foydalanuvchi tajribasi va ma'lumotlar barqarorligini ta'minlashga erishdik.
xususan Frontal tekshirishlar bilan API to'g'ridan-to'g'ri chaqirishi yoki o'tish so'rovlarini to'sib qo'yish mumkin emasligi sababli, orqa fonda tekshiruvlar albatta zarurbuni yana tasdiqlash imkoniyatiga ega bo'ldik.
5. MIME turini tekshirishdan asl rasmni tekshirishga
Ushbu ishda eng ko'p o'ylashim kerak bo'lgan qism rasm yuklashni tekshirish edi.
Birinchi amalga oshirishda faylning MIME turini faqat tekshirishva davom etar edi.
masalan, image/png, image/jpeg kabi turda yuborilganda, bu rasm fayli sifatida belgilanish usuli edi.
O'sha paytda bu yetarli deb o'yladim.
Ammo ko'rib chiqish jarayonida 'Rasm sifatida yuborilgan fayl haqiqatan ham rasmmi?' degan savol tug'ildi.
MIME turi mijoz tomonidan yuboriladigan ma'lumotdan iborat bo'lib, haqiqiy fayl mazmunini kafolatlamaydi.
Buni to'g'rilash uchun frondendda fayl imzosi (Signature) tekshirilishi, birinchi navbatda JPEG, PNG, GIF, BMP formatida ekanligini tasdiqlash uchun o'zgartirildi.
Shuningdek, backendda haqiqatan ham rasmni dekodlash imkoniyatini tekshirish uchun tasdiqlash logikasi qo'shildi.
private boolean isDecodableRasterImage(MultipartFile file) {
try (InputStream inputStream = file.getInputStream()) {
BufferedImage image = ImageIO.read(inputStream);
return image != null
&& image.getWidth() > 0
&& image.getHeight() > 0;
} catch (IOException e) {
return false;
}
}
MIME turidan haqiqiy rasm ma'lumotigacha tasdiqlash mezonini kengaytirish orqali, rasm bo'lmagan fayllar yuklanishi holatlarini yanada ishonchli tarzda oldini olishmumkin bo'ldi.
6. Rasmni tahrirlashda ma'lumotlar to'g'riligi boshqaruvi
Shaxsiy jihatdan eng ta'sirli ish rasm tahrirlash funksiyasini yaxshilash edi.
Foydalanuvchi sharhni tahrirlash jarayonida quyidagi ishlarni amalga oshirishi mumkin.
-
Mavjud rasmni saqlab qolish
-
Mavjud rasmning bir qismini o'chirish
-
Yangi rasm qo'shish
-
Mavjud rasmni to'liq o'chirish
Foydalanuvchi nuqtai nazaridan oddiy o'zgartirish funksiyasi kabi ko'rinadi, lekin aslida bir vaqtning o'zida bir nechta ma'lumotlar o'zgaradi.
Asl fayl, fayl identifikatsiya ma'lumoti (clipId), mini-rasm ma'lumoti, sharh ma'lumotlaridoimo bir xil holatda bo'lishi kerak edi.
Agar faqat ba'zi ma'lumotlar o'zgartirilsa, asl fayl o'chiriladi, lekin sharh ma'lumotlari qolishi mumkin, yoki aksincha, ma'lumotlar o'chiriladi, lekin fayl davom etadi, shunday holatlar yuzaga kelishi mumkin.
Buni oldini olish uchunsaqlash kerak bo'lgan fayl va o'chirilishi kerak bo'lgan faylni aniq ajratva, tegishli ma'lumotlar bilan birga o'zgarishi uchun mantiqni tartibga keltirdik.
Bundan tashqari, oxirgi rasm o'chirilganda mini-rasm ma'lumotlari va tegishli identifikatsiya ma'lumotlarini ham olib tashlash uchun yaxshiladik.
Bu ishni amalga oshirayotganda, funksiyani amalga oshirishdan ko'ra ma'lumotlar orasidagi bog'lanishni izchil saqlash muhim bo'lishi mumkinligini his qildim.
7. Qo'llanish natijasi
Bu yaxshilash ishlarini o'tkazish orqali quyidagi ta'sirlarni erishdik.
|
Yaxshilash punktlari |
Tatbiq natijalari |
|---|---|
|
Matnning normalizatsiyasi |
Ma'lumotlar bir xillikni oshirish |
|
HTML teglarini bloklash |
XSS yuzaga kelish ehtimolini kamaytirish |
|
Rasmni tekshirishni kuchaytirish |
Noto'g'ri fayl yuklashni oldini olish |
|
Frontend va backend ikkita tekshirish |
Foydalanuvchi tajribasi va barqarorlikni oshirish |
|
Ma'lumotlar to'g'riligi boshqaruvi |
Fayl ma'lumotlari mos kelmasligini kamaytirish |
Har bir alohida ish kichik o'zgarish sifatida ko'rinishi mumkin.
Ammo haqiqiy ish muhitida bundaykichik tekshirish logikasi bir xizmat sifatiga katta ta'sirko'rsatishi mumkinligini tajriba qildim.
8. Yakunlash
Ushbu ishni amalga oshirayotganda funksiyalarni amalga oshirish va ishga barqarorlikning bir-biridan farqli jihatlari borligini yana bir bor his qildim.
Ekran to'g'ri ishlasa ham xizmat tamomlangan deb aytish qiyin.
Foydalanuvchi kutilmagan kirish yuborsa ham, tizim barqaror ishlashi kerak va bir nechta ma'lumotlar doimo bir xil holatda saqlanishi lozim.
XususanKirish qiymatini tasdiqlash va ma'lumotlar uyg'unligini boshqarishfoydalanuvchi to'g'ridan-to'g'ri his qila olmaydigan sohalardir.
Lekin bu ko'rinmaydigan jihatlar oxir-oqibat xizmat sifatini belgilaydi, deb o'ylayman.
Ushbu tajriba orqali funksiyalarni amalga oshirishdan tashqari, ma'lumotlar qanday saqlanadi va boshqariladi, ish jarayonida qanday muammolar yuzaga kelishi mumkinligini birga o'ylash odatini yana bir bor his qildim.
Kelayotgan ishda ham, funksiyalarni amalga oshirish bilan cheklanmay, ish muhitini ham hisobga oluvchi rivojlanishni davom ettirishni maqsad qilaman.
zero