JavaScript: validasi sisi klien vs sisi server

179

Mana yang lebih baik untuk melakukan validasi sisi klien atau sisi server?

Dalam situasi kami, kami menggunakan

  • jQuery dan MVC.
  • Data JSON untuk melewati antara View dan Controller kami.

Banyak validasi yang saya lakukan adalah memvalidasi data ketika pengguna memasukkannya. Sebagai contoh, saya menggunakan keypressacara tersebut untuk mencegah huruf-huruf dalam kotak teks, mengatur jumlah karakter maksimum dan angka dengan dalam kisaran.

Saya kira pertanyaan yang lebih baik adalah, Apakah ada manfaat untuk melakukan validasi sisi server dari sisi klien?


Jawaban yang luar biasa semuanya. Situs web yang kami miliki dilindungi kata sandi dan untuk basis pengguna kecil (<50). Jika mereka tidak menjalankan JavaScript, kami akan mengirimkan ninja. Tetapi jika kami merancang situs untuk semua orang, saya setuju untuk melakukan validasi di kedua sisi.

Brad8118
sumber
2
javascript dapat dinonaktifkan
Enrico Murru
Tidak ada cara pasti untuk memblokir pengguna yang menonaktifkan JavaScript. Jika pengguna datang ke halaman Anda dengan JS diaktifkan, dan kemudian menonaktifkannya, tidak ada yang bisa Anda lakukan. (Oke, Anda bisa menggunakan JS untuk mengimplementasikan kontrol pengiriman, sehingga itu akan berhenti berfungsi dalam skenario ini, tetapi ini bisa dilewati seperti yang lainnya.)
Stewart

Jawaban:

347

Seperti yang orang lain katakan, Anda harus melakukan keduanya. Inilah alasannya:

Sisi klien

Anda ingin memvalidasi input pada sisi klien terlebih dahulu karena Anda dapat memberikan umpan balik yang lebih baik kepada pengguna rata-rata . Misalnya, jika mereka memasukkan alamat email yang tidak valid dan pindah ke bidang berikutnya, Anda dapat segera menampilkan pesan kesalahan. Dengan cara itu pengguna dapat memperbaiki setiap bidang sebelum mereka mengirimkan formulir.

Jika Anda hanya memvalidasi di server, mereka harus mengirimkan formulir, mendapatkan pesan kesalahan, dan mencoba mencari masalahnya.

(Nyeri ini dapat dikurangi dengan meminta server merender ulang formulir dengan input asli pengguna diisi, tetapi validasi sisi klien masih lebih cepat.)

Sisi server

Anda ingin memvalidasi di sisi server karena Anda dapat melindungi terhadap pengguna jahat , yang dapat dengan mudah mem-bypass JavaScript Anda dan mengirimkan input berbahaya ke server.

Sangat berbahaya untuk mempercayai UI Anda. Tidak hanya mereka dapat menyalahgunakan UI Anda, tetapi mereka mungkin tidak menggunakan UI Anda sama sekali, atau bahkan browser . Bagaimana jika pengguna mengedit URL secara manual, atau menjalankan Javascript sendiri, atau menyesuaikan permintaan HTTP mereka dengan alat lain? Bagaimana jika mereka mengirim permintaan HTTP khusus dari curlatau dari skrip, misalnya?

( Ini bukan teoretis; misalnya, saya bekerja pada mesin pencari perjalanan yang mengirimkan kembali pencarian pengguna ke banyak maskapai mitra, perusahaan bus, dll, dengan mengirimkan POSTpermintaan seolah-olah pengguna telah mengisi formulir pencarian masing-masing perusahaan, kemudian berkumpul dan disortir semua hasil. Bentuk JS perusahaan-perusahaan itu tidak pernah dieksekusi, dan itu penting bagi kami bahwa mereka memberikan pesan kesalahan dalam HTML yang dikembalikan. Tentu saja, sebuah API akan menyenangkan, tetapi ini yang harus kami lakukan. )

Tidak mengizinkan hal itu tidak hanya naif dari sudut pandang keamanan, tetapi juga non-standar: klien harus diizinkan mengirim HTTP dengan cara apa pun yang mereka inginkan, dan Anda harus merespons dengan benar. Itu termasuk validasi.

Validasi sisi server juga penting untuk kompatibilitas - tidak semua pengguna, bahkan jika mereka menggunakan browser, akan mengaktifkan JavaScript.

Addendum - Desember 2016

Ada beberapa validasi yang bahkan tidak dapat dilakukan dengan benar dalam kode aplikasi sisi-server, dan sama sekali tidak mungkin dalam kode sisi klien , karena mereka bergantung pada keadaan database saat ini. Misalnya, "tidak ada orang lain yang mendaftarkan nama pengguna itu", atau "posting blog yang Anda komentari masih ada", atau "tidak ada reservasi yang tumpang tindih dengan tanggal yang Anda minta", atau "saldo akun Anda masih cukup untuk menutupi pembelian itu. . " Hanya database yang dapat dipercaya memvalidasi data yang tergantung pada data terkait. Pengembang secara teratur mengacaukan ini , tetapi PostgreSQL menyediakan beberapa solusi yang baik .

Nathan Long
sumber
30
Ini harus menjadi jawaban yang diterima, bahkan 6 tahun kemudian: P
Jacob McKay
17
Ya, saya ingin menunggu hampir 10 tahun untuk memastikan.
Brad8118
2
@idmosey "ini jelas melanggar prinsip KERING" Ya, yang berarti sakit bagi programmer seperti kita. Tapi bayangkan formulir pendaftaran. Jika menduplikasi pengetahuan "alamat email harus mengandung @" dalam kode klien berarti pengguna mendapatkan umpan balik yang lebih cepat dan lebih banyak dari mereka mendaftar, menghasilkan $ 100k pendapatan tambahan per tahun, itu lebih dari membayar biaya pemeliharaan tambahan. KERING adalah prinsip yang sangat baik, tetapi itu bukan satu-satunya pertimbangan. Kualitas kode benar-benar diukur dalam seberapa baik melayani pengguna dan organisasi dalam analisis biaya / manfaat.
Nathan Long
1
@ArunRaaj Ya, dan Anda akan menangkap sebagian besar masalah seperti itu, tetapi tidak dapat diandalkan 100%. Jika dua pengguna mengisi formulir pada saat yang sama, mereka mungkin diberi tahu bahwa itu user1adalah nama pengguna yang tersedia. Ketika mereka mengirim, mereka berdua akan mendapatkan nama pengguna yang sama kecuali Anda memeriksa kembali sisi server. Dan bahkan pemeriksaan dalam kode aplikasi server dapat memiliki masalah yang sama: dua permintaan masuk, yang pertama memeriksa database dan diberitahu OK, yang kedua memeriksa database dan diberitahu OK, yang pertama disimpan, yang kedua disimpan sebagai duplikat. Hanya kendala unik db yang menjamin keunikan.
Nathan Long
1
@NathanLong Validasi data yang peka terhadap kondisi lomba tidak sesulit kalimat ini membuatnya terdengar. Sangat merepotkan untuk melakukannya dengan benar, tetapi buat mekanisme reservasi yang menggunakan sumber daya yang disinkronkan untuk meminta. Jadi, jika pengguna mengetik "usernameA" suatu pemeriksaan keunikan pada server yang melarang beberapa panggilan simultan untuk memeriksa apakah unik; jika unik, cadangan juga dengan token sementara yang ditugaskan untuk klien yang juga dirilis jika nama pengguna yang berbeda diuji dengan ID sesi yang sama. Token akan kedaluwarsa setelah waktu yang wajar. Contoh: Cadangan kursi TicketMaster.
Elaskanator
79

Ya, validasi sisi klien dapat benar-benar dilewati, selalu. Anda perlu melakukan keduanya, sisi klien untuk memberikan pengalaman pengguna yang lebih baik, dan sisi server untuk memastikan bahwa input yang Anda dapatkan benar-benar divalidasi dan tidak hanya seharusnya divalidasi oleh klien.

Vinko Vrsalovic
sumber
43

Saya hanya akan mengulanginya, karena ini sangat penting:

Selalu validasi di server

dan menambahkan JavaScript untuk respons pengguna.

Toby Hede
sumber
31

Manfaat melakukan validasi sisi server daripada validasi sisi klien adalah validasi sisi klien dapat dilewati / dimanipulasi:

  • Pengguna akhir bisa menonaktifkan javascript
  • Data dapat dikirim langsung ke server Anda oleh seseorang yang bahkan tidak menggunakan situs Anda, dengan aplikasi khusus yang dirancang untuk melakukannya
  • Kesalahan Javascript pada halaman Anda (disebabkan oleh sejumlah hal) dapat mengakibatkan beberapa, tetapi tidak semua, validasi Anda berjalan

Singkatnya - selalu, selalu memvalidasi sisi server dan kemudian mempertimbangkan validasi sisi klien sebagai tambahan "tambahan" untuk meningkatkan pengalaman pengguna akhir.

rampok
sumber
18

Anda harus selalu memvalidasi di server.

Juga memiliki validasi pada klien bagus untuk pengguna, tetapi sama sekali tidak aman.

Peter Boughton
sumber
9

Yah, aku masih menemukan ruang untuk menjawab.

Selain jawaban dari Rob dan Nathan, saya ingin menambahkan bahwa memiliki validasi sisi klien penting. Ketika Anda menerapkan validasi pada formulir web Anda, Anda harus mengikuti panduan ini:

Sisi klien

  1. Harus menggunakan validasi sisi klien untuk memfilter permintaan asli yang berasal dari pengguna asli di situs web Anda.
  2. Validasi sisi klien harus digunakan untuk mengurangi kesalahan yang mungkin terjadi selama pemrosesan sisi server.
  3. Validasi sisi klien harus digunakan untuk meminimalkan round-trip sisi-server sehingga Anda menghemat bandwidth dan permintaan per pengguna.

Sisi server

  1. Anda TIDAK HARUS menganggap validasi yang berhasil dilakukan di sisi klien adalah 100% sempurna. Tidak masalah bahkan jika melayani kurang dari 50 pengguna. Anda tidak pernah tahu pengguna / emplyee mana yang berubah menjadi "jahat" dan melakukan aktivitas berbahaya dengan mengetahui Anda tidak memiliki validasi yang sesuai.
  2. Bahkan jika itu sempurna dalam hal memvalidasi alamat email, nomor telepon atau memeriksa beberapa input yang valid itu mungkin berisi data yang sangat berbahaya. Yang perlu disaring di sisi server tidak peduli apakah itu benar atau salah.
  3. Jika validasi sisi klien dilewati, validasi sisi server Anda datang untuk menyelamatkan Anda dari segala potensi kerusakan pada pemrosesan sisi server Anda. Baru-baru ini, kita telah mendengar banyak cerita tentang SQL Suntikan dan jenis teknik lain yang mungkin diterapkan untuk mendapatkan beberapa manfaat jahat.

Kedua jenis validasi memainkan peran penting dalam ruang lingkup masing-masing tetapi yang paling kuat adalah sisi server. Jika Anda menerima 10k pengguna pada satu titik waktu maka Anda pasti akan memfilter jumlah permintaan yang datang ke server web Anda. Jika Anda menemukan ada satu kesalahan seperti alamat email yang tidak valid maka mereka memposting kembali formulir itu lagi dan meminta pengguna Anda untuk memperbaikinya yang pasti akan memakan sumber daya dan bandwidth server Anda. Jadi lebih baik Anda menerapkan validasi javascript. Jika javascript dinonaktifkan maka validasi sisi server Anda akan datang untuk menyelamatkan dan saya yakin hanya beberapa pengguna yang mungkin secara tidak sengaja menonaktifkannya sejak 99,99% situs web menggunakan javascript dan sudah diaktifkan secara default di semua browser modern.

KMX
sumber
Saya telah melihat orang-orang lalai untuk melindungi terhadap injeksi kode sama sekali, apalagi melakukannya hanya di sisi klien. Dan tidak ada referensi untuk injeksi kode yang lengkap tanpa tautan ke ini: xkcd.com/327 :)
Stewart
8

Anda dapat melakukan validasi sisi Server dan mengirim kembali objek JSON dengan hasil validasi untuk setiap bidang, menjaga Javascript klien seminimal mungkin (hanya menampilkan hasil) dan masih memiliki pengalaman ramah pengguna tanpa harus mengulangi diri Anda sendiri pada klien dan server.

Jonathan
sumber
3
Mudah digunakan? Mungkin. Hampir instan dan bermentega halus? Mungkin tidak.
quadrupleslap
4

Sisi klien harus menggunakan validasi dasar melalui tipe input HTML5 dan atribut pola dan karena ini hanya digunakan untuk peningkatan progresif untuk pengalaman pengguna yang lebih baik (Bahkan jika mereka tidak didukung pada <IE9 dan safari, tetapi kami tidak bergantung pada mereka). Tetapi validasi utama harus terjadi di sisi server ..

adardesign
sumber
"Tetapi validasi utama harus terjadi di sisi server." Tidak seharusnya, harus.
Stewart
2

JavaScript dapat dimodifikasi saat runtime.

Saya menyarankan pola membuat struktur validasi di server, dan berbagi ini dengan klien.

Anda akan memerlukan logika validasi terpisah di kedua ujungnya, mis:

"required"atribut di inputssisi klien

field.length > 0 sisi server.

Tetapi menggunakan spesifikasi validasi yang sama akan menghilangkan beberapa redundansi (dan kesalahan) dari validasi mirroring di kedua ujungnya.

TaylorMac
sumber
2

Validasi data sisi klien dapat berguna untuk pengalaman pengguna yang lebih baik: misalnya, saya pengguna yang salah mengetik alamat emailnya, tidak boleh menunggu sampai permintaannya diproses oleh server jarak jauh untuk mempelajari tentang kesalahan ketik yang dia lakukan.

Namun demikian, sebagai penyerang dapat melewati validasi sisi klien (dan bahkan mungkin tidak menggunakan browser sama sekali), validasi sisi server diperlukan, dan harus menjadi gerbang nyata untuk melindungi backend Anda dari pengguna jahat.

Billal Begueradj
sumber
1

Saya menemukan tautan menarik yang membuat perbedaan antara kesalahan kotor, sistematis, acak.

Client-Side validationsangat cocok untuk mencegah kesalahan kotor dan acak. Biasanya panjang maksimal untuk tekstur dan input. Jangan meniru aturan validasi sisi server; berikan aturan validasi bruto, aturan praktis (mis. 200 karakter di sisi klien; ndi sisi server yang ditentukan oleh aturan bisnis yang kuat).

Server-side validationsangat cocok untuk mencegah kesalahan sistematis; itu akan menegakkan aturan bisnis.

Dalam proyek yang saya ikuti, validasi dilakukan di server melalui permintaan ajax. Pada klien saya menampilkan pesan kesalahan yang sesuai.

Bacaan lebih lanjut: kesalahan kotor, sistematis, acak:

https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO

roland
sumber
-2

Jika Anda melakukan validasi ringan, yang terbaik adalah melakukannya pada klien. Ini akan menghemat lalu lintas jaringan yang akan membantu server Anda bekerja lebih baik. Jika jika rumit validasi yang melibatkan menarik data dari database atau sesuatu, seperti kata sandi, maka yang terbaik adalah melakukannya di server tempat data dapat diperiksa dengan aman.

Tom
sumber
2
Apa yang Anda ajukan bukanlah ide terbaik. Pengguna dapat selalu melewati validasi sisi klien dan mengirimkan apa pun yang mereka inginkan ke basis data.
kremuwa