Validasi input data selalu merupakan perjuangan internal bagi saya.
Di ambang menambahkan kerangka kerja dan kode keamanan nyata ke proyek penulisan ulang aplikasi lawas kami (yang sejauh ini cukup banyak menyimpan kode keamanan warisan-kartu yang kuat dan validasi data), saya bertanya-tanya lagi tentang berapa banyak yang harus saya validasikan, dimana, dll.
Selama 5 tahun saya sebagai pengembang Java profesional, saya membuat dan menyempurnakan aturan pribadi saya untuk validasi input data dan langkah-langkah keamanan. Karena saya ingin meningkatkan metode saya, saya ingin mendengar beberapa ide dari kalian. Aturan dan prosedur umum baik-baik saja, dan yang khusus Java juga.
Ringkasnya, ini adalah pedoman saya (terbuka pada gaya aplikasi web 3-tier), dengan penjelasan singkat:
Sisi klien tingkat pertama (browser): validasi minimal, hanya aturan yang tidak berubah-ubah (bidang email wajib, harus memilih satu item, dan sejenisnya); penggunaan validasi tambahan seperti "antara 6 dan 20 karakter" lebih jarang, karena ini meningkatkan pekerjaan pemeliharaan pada perubahan (dapat ditambahkan setelah kode bisnis stabil);
Sisi server tingkat 1 (penanganan komunikasi web, "pengontrol"): Saya tidak memiliki aturan untuk yang ini, tetapi saya percaya hanya manipulasi data dan kesalahan perakitan / penguraian yang harus ditangani di sini (bidang ulang tahun bukan tanggal yang valid); menambahkan validasi lebih lanjut di sini dengan mudah membuatnya menjadi proses yang sangat membosankan;
2nd tier (lapisan bisnis): validasi solid, tidak kurang; input format data, rentang, nilai, pemeriksaan keadaan internal jika metode tidak dapat dipanggil kapan saja, peran / izin pengguna, dan sebagainya; gunakan sesedikit mungkin input data pengguna, ambil kembali dari database jika diperlukan; jika kita mempertimbangkan mengambil data basis data sebagai input juga, saya hanya akan memvalidasinya jika beberapa data spesifik diketahui tidak cukup dapat diandalkan atau rusak pada DB - pengetikan yang kuat melakukan sebagian besar pekerjaan di sini, IMHO;
Tingkat 3 (lapisan data / DAL / DAO): tidak pernah percaya banyak validasi diperlukan di sini, karena hanya lapisan bisnis yang seharusnya mengakses data (validasi mungkin pada beberapa kasus seperti "param2 tidak boleh nol jika param1 benar"); Namun perhatikan, bahwa ketika saya maksudkan "di sini" maksud saya "kode yang mengakses database" atau "metode pelaksana SQL", database itu sendiri benar-benar kebalikannya;
database (model data): perlu dipikirkan dengan baik, kuat dan dapat diterapkan sendiri untuk menghindari data yang salah dan korup pada DB sebanyak mungkin, dengan kunci primer yang baik, kunci asing, kendala, tipe data / panjang / ukuran / presisi dan sebagainya - Saya akan meninggalkan pemicu ini, karena mereka memiliki diskusi pribadi mereka sendiri.
Saya tahu validasi data awal itu bagus dan dari segi kinerja, tetapi validasi data berulang adalah proses yang membosankan, dan saya akui bahwa validasi data itu sendiri cukup menjengkelkan. Itu sebabnya begitu banyak coders melewatkannya atau melakukannya di tengah jalan. Selain itu, setiap validasi duplikat adalah bug yang mungkin terjadi jika tidak disinkronkan setiap saat. Itulah alasan utama saya saat ini lebih suka membiarkan sebagian besar validasi naik ke lapisan bisnis, dengan mengorbankan waktu, bandwidth dan CPU, pengecualian ditangani berdasarkan kasus per kasus.
Jadi, apa pendapat Anda tentang ini? Opini yang berlawanan? Apakah Anda memiliki prosedur lain? Referensi ke topik seperti itu? Setiap kontribusi adalah valid.
Catatan: jika Anda memikirkan cara Java untuk melakukan sesuatu, aplikasi kami berbasis pada Spring MVC dan MyBatis (kinerja dan model basis data yang buruk mengesampingkan solusi ORM); Saya berencana untuk menambahkan Spring Security sebagai penyedia keamanan kami ditambah JSR 303 (Hibernate Validator?)
Terima kasih!
Sunting: beberapa klarifikasi tambahan pada layer ke-3.
Jawaban:
Validasi Anda harus konsisten. Jadi, jika pengguna memasukkan beberapa data di formulir web yang dianggap valid, ia tidak boleh ditolak oleh lapisan basis data karena beberapa kriteria yang tidak Anda terapkan di sisi klien.
Sebagai pengguna, tidak ada yang lebih menyebalkan dengan memasukkan satu halaman data yang tampaknya benar hanya untuk diberitahu setelah perjalanan pulang-pergi yang signifikan ke database bahwa ada sesuatu yang salah. Ini akan benar terutama jika saya telah melakukan beberapa validasi klien dalam proses.
Anda perlu memiliki validasi di berbagai level saat Anda mengeksposnya dan berpotensi tidak memiliki kendali atas siapa yang memanggil mereka. Jadi, Anda perlu mengatur (sejauh mungkin) untuk validasi Anda untuk didefinisikan di satu tempat dan menelepon dari mana pun itu diperlukan. Bagaimana ini diatur akan tergantung pada bahasa dan kerangka kerja Anda. Di Silverlight (misalnya) Anda dapat mendefinisikannya di sisi server dan dengan atribut yang sesuai, ia akan disalin ke sisi klien untuk digunakan di sana.
sumber
Dalam sistem relasional, saya melihatnya sebagai pendekatan tiga lapis. Setiap lapisan dibatasi oleh yang di bawah ini:
Yang ideal Jawaban untuk ini akan menjadi sebuah sistem yang memungkinkan Anda menentukan kendala sama sekali tiga lapisan di satu tempat. Ini akan melibatkan beberapa pembuatan kode untuk SQL, dan setidaknya beberapa validasi berbasis data untuk klien dan server.
Saya tidak tahu apakah ada peluru perak di sini ... tetapi karena Anda berada di JVM saya sarankan melihat Rhino untuk setidaknya berbagi kode validasi JavaScript antara klien dan server. Jangan tulis validasi input Anda dua kali.
sumber
Ini sangat salah. Tempat paling penting untuk memiliki validasi adalah di dalam database itu sendiri. Data hampir selalu dipengaruhi oleh lebih dari aplikasi (bahkan ketika Anda pikir itu tidak akan terjadi) dan itu tidak bertanggung jawab untuk tidak menempatkan kontrol yang tepat ke dalam database. Ada lebih banyak kehilangan integritas data dari keputusan untuk tidak melakukan ini daripada faktor lainnya. Integritas data sangat penting untuk penggunaan jangka panjang dari database. Saya belum pernah melihat database yang gagal menegakkan aturan integritas di level database yang berisi data yang baik (dan saya telah melihat data dalam ribuan database).
Dia mengatakan itu lebih baik daripada saya: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress
sumber
Semua hal di atas membuat asumsi bahwa pengembang dan pengelola adalah sempurna dan menulis kode sempurna yang selalu berjalan dengan sempurna. Rilis perangkat lunak masa depan tahu tentang semua asumsi yang Anda buat dan tidak pernah didokumentasikan, dan pengguna dan peretas yang memasukkan data ke dalam sistem dengan cara yang tidak pernah Anda bayangkan.
Tentu, terlalu banyak validasi adalah hal yang buruk, tetapi dengan asumsi program, jaringan dan OS sempurna, peretas tidak akan bisa menembus firewall Anda, DBA tidak akan secara manual "mengubah" database mungkin lebih buruk.
Gambarlah lingkaran batas di sekeliling benda-benda, identifikasi mode kegagalan yang dilindunginya dan terapkan tingkat pemeriksaan yang sesuai untuk batas itu. Misalnya, basis data Anda seharusnya tidak pernah melihat data yang tidak valid, tetapi bagaimana itu bisa terjadi dan bagaimana jika itu terjadi? Siapa pengguna Anda, berapa biaya kegagalan?
Mempelajari model keamanan dunia fisik, keamanan harus berlapis-lapis, seperti bawang. Satu tembok tebal dianggap keamanannya buruk. Validasi data harus dipertimbangkan dengan cara yang sama.
sumber
Dua pendek, aturan umum untuk validasi:
Jika Anda akan memanggil apa pun yang tidak menjamin itu akan mengembalikan sesuatu (kesalahan, pengecualian) untuk memberi tahu Anda tentang input yang tidak valid dengan cara yang dapat Anda sampaikan kembali ke pemanggil Anda, validasikanlah.
Jika Anda akan melakukan hal lain dengan data (membuat keputusan, menghitung, menyimpan, dll.), Validasikan.
sumber