İstemci tarafı ve sunucu tarafı doğrulamalarını tek bir yerden yönetme


17

Bir Bu durumda gemide% 100 değilim gerektiğini kesinlikle istemci tarafı ve sunucu tarafı veri doğrulama hem kullanın.

Ancak çalıştığım çerçevelerde ve ortamlarda gördüğüm yaklaşımlar hiç KURU olmamıştı. Çoğu zaman bir plan veya kalıp yoktur - onaylar model spesifikasyonunda yazılır ve onaylar görünümde formda yazılır. (Not: İlk deneyimimin çoğu RaQ, Sinatra ve jQuery ile PHP ile)

Bir bakıma, bir dizi doğrulama verildiğinde (örn. Model adı, alan (lar), durum), hem gerekli istemci tarafı hem de sunucu tarafı malzemeyi üretebilecek bir jeneratör oluşturmak zor olmayacak gibi görünüyor. Alternatif olarak, böyle bir araç, sunucu tarafı doğrulamaları alabilir ( validatesActiveRecord modelindeki kod gibi ) ve daha sonra forma uygulanacak olan istemci tarafı doğrulamaları (jQuery eklentileri gibi) oluşturabilir.

Açıkçası, yukarıdaki sadece resmi bir teklif değil, "hey bu fikrim vardı". Bu tür şeyler, fikir bana çarptığında göründüğünden kesinlikle daha zordur.

Bu beni şu soruya getiriyor: Veri doğrulama için "bir kez yaz, sunucuda ve istemcide çalıştır" tekniğini nasıl tasarlarsınız?

İlgili alt konular: Belirli çerçeveler veya istemci-sunucu teknolojileri için böyle araçlar var mı? Yalnızca tek bir doğrulama kümesini korumaya çalışırken önemli sorunlar veya zorluklar nelerdir?

Yanıtlar:


6

Sınırlı deneyimlerime göre, validasyonun gerekli olduğu noktalar

  1. HTML kullanarak sunum seviyesi,
  2. sunum sonrası düzeyinde (yani, Javascript doğrulaması),
  3. birden çok alan arasındaki etkileşimlerin birlikte doğrulanması gereken kombinasyon düzeyinde,
  4. iş mantığı düzeyinde ve
  5. veritabanı düzeyinde.

Her birinin farklı dilleri, zamanlamaları ve tetikleyicileri vardır. Örneğin, tüm kayıt, tutarlı bir durumda önce bir alanı doğrulamak için biraz mantıklı sürece sadece tek parça doğrulamak istiyorum. Veritabanı düzeyindeki kısıtlamalar, yalnızca bir taahhütten önce uygulanmalıdır ve kolaylıkla parça halinde yapılamaz.

İlgili bir kavram, verileri temsil etmenin her seviye arasında değişmesidir. Basit bir örnek, bir web tarayıcısının belki de CP1290 gibi bir metni temsil ederken, veritabanı onu UTF-8'de temsil eder; iki dizenin uzunlukları farklılık gösterir, bu nedenle zorlayıcı uzunluk kısıtlamaları garipleşir.


Evet, farklı diller ve çerçeveler bunu pratik yapmıyor. "Geri alınamaz" çünkü yeterli kaynakla yapılabilir ancak dillere ve diller arasında otomatik dönüştürücüler yazmak çok büyük bir iştir. Makul bir zaman diliminde yapmak ve daha sonra ilgili teknolojiler değiştikçe bunu sürdürmek çok iş olacaktır.
Michael Durrant

Birçok sunucu tarafı doğrulamasının (örneğin bir alanın benzersizliği) tarayıcıda gerçekleştirilemeyeceği kesinlikle doğrudur. Ancak, istemciye güvenemeyeceğiniz için, istemci tarafı doğrulamalarının sunucuda tekrarlanması gerektiği de doğrudur. DRYing'in özellikle yararlı olduğunu gördüğüm yer burası. Örneğin, form_forotomatik olarak istemci tarafı doğrulama kodu çok yararlı olmasını sağlamak için Rails 'uzanan bir mücevher görebiliyordu .
Dan

5

Genellikle çözümleri sınırlayan bir husus ağ gidiş dönüşüdür. İstemcinin ağ üzerinden mesaj göndermeden kullanıcı verilerini doğrulaması gerekiyor. Başka bir deyişle, kullanıcı gönder düğmesine bastığında, istemcinin verileri yerel olarak doğrulaması gerekir.

İlk olarak, bu sınırlamaya sahip olmadığımızı varsayalım. Doğrulama sorunlarını dile getirmede iyi bir ağ uç noktası ile iletişim kurabiliriz. Örneğin, vanilya HTTP hata kodu ile yanıt vermek yerine yeni Kullanıcı kaydınızı gönderdiğinizde, sorunları ayrıntılı bir JSON yanıtı döndürebilir ve istemci, karşılaştığı sorunları yansıtacak şekilde ekranı akıllıca güncelleyebilir. Bitiş noktası bir doğrulama ağ geçidinin rolünü oynar.

KURU ama dezavantajları yok. İlk olarak, sunucumuzun istemci tarafında ele alınabilecek doğrulamalarla vergilendirilmesi ağ gidiş dönüşüne bağlıdır. İkincisi, tasarım tüm CRUD işlemlerinin uç noktalarımız üzerinden gerçekleşeceğini öngörüyor, ancak geliştiriciler ve süreçler doğrudan veritabanına giderek veri erişim katmanımızı atladığında ne olacak ?

Bu dezavantajların üstesinden gelmek için çözümümüzü tekrar gözden geçirelim. Bunun yerine doğrulamalarımızı meta veri olarak saklayıp iletelim:

{field: 'username', type: 'required'}
{field: 'username', type: 'unique'} //requires a network roundtrip
{field: 'password', type: 'length', min: 10, max: 50}
{field: 'password', type: 'contains', characters: ['upper', 'special', 'letter', 'number']}

Hem istemci hem de sunucu, bu verileri yorumlamak ve uygulamak için bazı mekanizmalara (örneğin bir motor) sahip olacaktır. (Bazıları bunu bildirici kısmı yorumlayıcısından ayırdığı için serbest monad olarak adlandırır.) JavaScript'te her bilgi parçasını çalışma işlevleriyle eşleştirebiliriz. Önyükleme için, veritabanımız da dahil olmak üzere mimarimizin herhangi bir katmanını doğrulamaları zorunlu kılmayı öğretebiliriz.


Bir alan web tarayıcısı, aktarım, uygulama dili ve veritabanında farklı şekilde temsil edildiğinde bir alanı nasıl tanımlarsınız? Örneğin, bir dize alanını temsil etmek için gereken bayt sayısı, CP1290 (IE), UTF-8 (JSON), UTF-8 (C #) veya UCS-16 (Oracle) kullanıldığında değişir. Uzunluk kısıtı ne demektir? Daha da önemlisi, tarayıcı için karakter temsili tarayıcıya ve işletim sistemine bağlı olduğunda?
BobDalgleish

Bu kısıtlamalar insanlara zihinsel bir model olarak yöneliktir. Bir programcı olarak işiniz, makinedeki farklılıkları soyutlamaktır, böylece kişinin herhangi bir teknik farklılığa dikkat etmesi gerekmez.
Mario T. Lanza

Konuyu tamamen kaçırdınız. Şimdiye kadar, hiç kimse bir spesifikasyonla, uçtan uca doğrulamaya izin veren bir soyutlama sunmadı. OP'den "bir kez yaz" ifadesi, farklı aşamaları ele alan farklı maddelere sahip olmanın uygun olmadığını ima eder. Benzer şekilde, önerilen doğrulamanızda alanlar arası veya interobject doğrulamasını ele alan hiçbir şey göremiyorum.
BobDalgleish

Alanlar arası / nesne doğrulamaları çok fazla değildir. Meta veriler sadece ilişkiyi temsil eder. Bir kez yaz, bir kez tek bir doğrulama yazmam ve bunu yapan birden fazla sitede uygulanmasını ima eder. Bir tabloya meta veriler eklersiniz. Bu meta veriler herhangi bir site tarafından alınır ve basit bir sınıf / yardımcı program / motor kısıtlamayı zorlar.
Mario T. Lanza

1
Böyle bir onaylama dili son derece yararlı olacaktır. UI yoğun web uygulamalarıyla ilgili kodun üçte birinin yerini alabilir.
BobDalgleish

2

Bunun bir yolu, hem sunucu hem de istemci tarafında aynı dili / çerçeveyi kullanmak olacaktır.

Örneğin

Node.js :: JavaScript'te İstemci / Sunucu GET :: Java'da İstemci / Sunucu

Bu durumda, "Etki Alanı Nesnesi" kodunun çoğu yaygındır ve bu doğrulama içerir. Framework kodu gerektiği gibi çağıracaktır. Örn. Aynı kod, tarayıcıdan "gönder" öncesinde ve sunucu tarafı web hizmetinde çağrılır.

EDIT (Haziran / 2014): Java 8 ile, JS doğrulama kodunu Java Uygulamalarına da entegre etmek artık çok kolay. Java 8, daha kalıcı olan yeni bir JS yürütme motoruna sahiptir (Örn: invokeDynamic'i kullanır).


SQL veritabanına gelince bunun nasıl çalışacağından emin değilim.
Michael Durrant

Ayrıca, tarayıcının ve işletim sisteminin giriş etki alanını etkilemesi sorununu da çözmez.
BobDalgleish

@Micheal Durrant, Veritabanı doğrulaması DB kısıtlamaları (yabancı anahtar, benzersiz vb.) Olarak uygulanır. BobDalgleish, 1. Tarayıcı / OS uyumluluğu sorunu Tarayıcı'ya göre çalışma zamanını ayarlayan bir Kütüphane kullanılarak azaltılabilir (Sencha gibi) 2. Tarayıcı uyumluluğu uygunluk gibi kodun "mantıksal" bölümlerini etkilemez, uyumluluk sorunları genellikle DOM / UI Oluşturma etrafında.
Verma

0

Ben sadece aynı problemi düşünüyordum. Hem C # hem de javascript soyut bir sözdizimi ağacı almak için ANTLR kullanmayı düşünüyordum. Oradan, dilde belirtilen eylemleri doğrulanacak nesnelere uygulamak için ağaç yürüteçlerini kullanırsınız.

Böylece, gerekli doğrulama işleminin bir açıklamasını istediğiniz yerde saklayabilirsiniz - muhtemelen veritabanında.

Soruna bu şekilde yaklaşırım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.