Quản lý xác nhận phía máy khách và phía máy chủ ở một nơi


17

Tôi 100% trên tàu với trường hợp một người chắc chắn nên sử dụng cả xác thực dữ liệu phía máy khách và phía máy chủ.

Tuy nhiên, trong các khuôn khổ và môi trường tôi đã làm việc, các phương pháp tôi đã thấy chưa bao giờ là KHÔ. Hầu hết thời gian không có kế hoạch hoặc mẫu - các xác nhận được viết trong thông số mô hình và các xác nhận được viết theo mẫu trên dạng xem. (Lưu ý: Hầu hết trải nghiệm đầu tay của tôi là với Rails, Sinatra và PHP w / jQuery)

Thay đổi nó, có vẻ như sẽ không khó để tạo ra một trình tạo, với một bộ xác nhận hợp lệ (ví dụ như tên mô hình, trường, điều kiện), có thể tạo ra cả vật liệu phía máy khách và phía máy chủ cần thiết. Cách khác, một công cụ như vậy có thể lấy các xác nhận phía máy chủ (chẳng hạn như validatesmã trong mô hình ActiveRecord) và tạo các xác thực phía máy khách (như các plugin jQuery, sau đó sẽ được áp dụng cho biểu mẫu.

Rõ ràng, ở trên chỉ là một "hey tôi đã có ý tưởng này", và không phải là một đề xuất chính thức. Điều này chắc chắn là khó khăn hơn nó tưởng khi ý tưởng tấn công tôi.

Điều đó mang lại cho tôi câu hỏi: Làm thế nào bạn sẽ tiếp cận việc thiết kế một kỹ thuật "viết một lần, chạy trên máy chủ và máy khách" để xác thực dữ liệu?

Chủ đề phụ liên quan: Các công cụ như thế có tồn tại cho bất kỳ khuôn khổ cụ thể hoặc công nghệ máy chủ-máy khách nào không? Các vấn đề hay thách thức chính với việc cố gắng duy trì chỉ một bộ xác nhận là gì?

Câu trả lời:


6

Theo kinh nghiệm hạn chế của tôi, các điểm yêu cầu xác nhận là

  1. Cấp độ trình bày bằng HTML,
  2. ở cấp độ sau khi trình bày (nghĩa là xác thực Javascript),
  3. ở cấp độ kết hợp nơi các tương tác giữa nhiều trường phải được xác nhận cùng nhau,
  4. ở cấp độ logic kinh doanh và
  5. ở cấp cơ sở dữ liệu.

Mỗi người trong số họ có ngôn ngữ, thời gian và kích hoạt khác nhau. Chẳng hạn, việc xác thực một trường trước khi toàn bộ bản ghi ở trạng thái nhất quán sẽ không có ý nghĩa gì, trừ khi bạn muốn xác thực chỉ một phần. Các ràng buộc ở cấp cơ sở dữ liệu chỉ được áp dụng ở cuối trước khi cam kết và không thể thực hiện một cách khôn ngoan.

Một khái niệm liên quan là đại diện cho dữ liệu khác nhau giữa mỗi cấp độ. Một ví dụ đơn giản là một trình duyệt web đại diện cho một đoạn văn bản, có lẽ là CP1290, trong khi cơ sở dữ liệu đại diện cho nó trong UTF-8; độ dài của hai chuỗi khác nhau nên việc thực thi các ràng buộc về độ dài trở nên khó xử.


yup, các ngôn ngữ và khung khác nhau làm cho điều này không thực tế. Không phải là "không thể hoàn tác" bởi vì với đủ tài nguyên có thể được thực hiện nhưng việc viết bộ chuyển đổi tự động sang và giữa các ngôn ngữ là một nhiệm vụ HẤP DẪN. Làm điều đó trong một khung thời gian hợp lý và sau đó duy trì nó khi các công nghệ liên quan thay đổi sẽ có rất nhiều công việc.
Michael Durrant

Điều chắc chắn là nhiều xác nhận phía máy chủ (ví dụ: tính duy nhất của một trường) không thể được thực hiện trong trình duyệt. Tuy nhiên, cũng đúng là mọi xác nhận phía máy khách cần phải được lặp lại trong máy chủ, vì bạn không thể tin tưởng vào máy khách. Đó là nơi tôi thấy việc DRYing trở nên đặc biệt hữu ích. Ví dụ: tôi có thể thấy một viên ngọc mở rộng Rails ' form_forđể tự động cung cấp mã xác thực phía máy khách rất hữu ích.
Dan

5

Một xem xét thường giới hạn các giải pháp là chuyến đi khứ hồi mạng. Máy khách có nhiệm vụ xác thực dữ liệu người dùng mà không gửi tin nhắn qua mạng. Nói cách khác, khi người dùng nhấn nút gửi, khách hàng có nghĩa vụ xác thực dữ liệu cục bộ.

Đầu tiên, hãy giả sử rằng chúng ta không có giới hạn này. Chúng tôi có thể liên lạc với một điểm cuối mạng rất tốt trong việc xác định các vấn đề xác nhận. Ví dụ: khi bạn gửi bản ghi Người dùng mới của mình cho nó, thay vì phản hồi bằng mã lỗi HTTP vanilla, nó có thể trả về một phản hồi JSON chi tiết ghi rõ các vấn đề và khách hàng sẽ cập nhật thông minh màn hình để phản ánh các vấn đề mà nó gặp phải. Điểm cuối đóng vai trò của một cổng xác nhận.

Đó là DRY nhưng không phải không có nhược điểm. Đầu tiên, nó phụ thuộc vào việc làm tròn thuế mạng máy chủ của chúng tôi với các xác nhận có thể đã được xử lý phía máy khách. Thứ hai, thiết kế dự đoán rằng tất cả các hoạt động CRUD sẽ xảy ra thông qua các điểm cuối của chúng tôi, nhưng còn khi các nhà phát triển và quy trình bỏ qua lớp truy cập dữ liệu của chúng tôi bằng cách truy cập trực tiếp vào cơ sở dữ liệu thì sao?

Hãy xem xét lại giải pháp của chúng tôi để khắc phục những nhược điểm này. Thay vào đó, hãy lưu trữ và truyền đạt các xác nhận của chúng tôi dưới dạng siêu dữ liệu:

{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']}

Cả máy khách và máy chủ sẽ có một số cơ chế (ví dụ: một công cụ) để diễn giải và áp dụng dữ liệu này. (Một số người gọi đây là đơn nguyên miễn phí vì nó tách phần khai báo khỏi trình thông dịch của nó.) Trong JavaScript, chúng ta có thể ánh xạ từng phần thông tin vào các chức năng làm việc. Để khởi động, chúng tôi có thể dạy bất kỳ lớp nào trong kiến ​​trúc của chúng tôi, bao gồm cả cơ sở dữ liệu của chúng tôi, để thực thi các xác nhận một cách nhất quán.


Làm thế nào để bạn mô tả một trường khi một trường được thể hiện khác nhau trong trình duyệt web, vận chuyển, ngôn ngữ thực hiện và cơ sở dữ liệu? Chẳng hạn, số byte cần thiết để thể hiện trường chuỗi thay đổi khi sử dụng CP1290 (IE), UTF-8 (JSON), UTF-8 (C #) hoặc UCS-16 (Oracle). Một ràng buộc chiều dài có nghĩa là gì? Quan trọng hơn đối với trình duyệt, khi biểu diễn ký tự phụ thuộc vào trình duyệt và hệ điều hành?
BobDalgleish

Những ràng buộc này nhằm mục đích như một mô hình tinh thần ở con người. Công việc của bạn là một lập trình viên là trừu tượng hóa sự khác biệt của máy để người đó không phải quan tâm đến bất kỳ sự khác biệt kỹ thuật nào.
Mario T. Lanza

Bạn hoàn toàn bỏ lỡ điểm. Cho đến nay, không ai trình bày một sự trừu tượng cho phép xác nhận từ đầu đến cuối, với một đặc điểm kỹ thuật. Từ OP, "viết một lần" ngụ ý rằng việc có các mệnh đề khác nhau giải quyết các giai đoạn khác nhau không đủ điều kiện. Tương tự, tôi thấy không có gì trong xác nhận đề xuất của bạn giải quyết xác thực liên trường hoặc liên từ.
BobDalgleish

Xác nhận giữa các trường / đối tượng không phải là quá nhiều. Siêu dữ liệu chỉ đại diện cho mối quan hệ. Viết một lần ngụ ý rằng tôi viết một xác nhận một lần và nó đã được thi hành tại nhiều trang web, điều này thực hiện. Bạn thêm siêu dữ liệu vào một bảng. Siêu dữ liệu đó được nhận bởi bất kỳ trang web nào và một lớp / tiện ích / công cụ đơn giản thực thi ràng buộc.
Mario T. Lanza

1
Một ngôn ngữ xác nhận như vậy sẽ vô cùng hữu ích. Nó có thể thay thế một phần ba mã liên quan đến các ứng dụng web chuyên sâu về UI.
BobDalgleish

2

Một cách sẽ là sử dụng cùng một ngôn ngữ / khung trên cả phía máy chủ và máy khách.

Ví dụ

Node.js :: Máy khách / Máy chủ trong JavaScript GET :: Máy khách / Máy chủ trong Java

Trong trường hợp này, hầu hết mã "Đối tượng miền" sẽ phổ biến, bao gồm xác nhận. Framework sẽ gọi mã theo yêu cầu. Ví dụ: Mã tương tự sẽ được gọi trong trình duyệt trước khi "gửi" và trên dịch vụ web phía máy chủ.

EDIT (Tháng 6/2014): Với Java 8, giờ đây cũng dễ dàng tích hợp mã xác thực JS trong Ứng dụng Java. Java 8 có một công cụ thực thi JS mới thường xuyên hơn (Ví dụ: nó sử dụng invokeDocate).


Khi nói đến cơ sở dữ liệu SQL, không chắc nó sẽ hoạt động như thế nào.
Michael Durrant

Nó cũng không giải quyết được vấn đề trình duyệt và hệ điều hành ảnh hưởng đến miền đầu vào.
BobDalgleish

@Micheal Durrant, Để xác thực cơ sở dữ liệu được triển khai dưới dạng các ràng buộc DB (chẳng hạn như khóa ngoại, duy nhất, v.v.). BobDalgleish, 1. Vấn đề về khả năng tương thích trình duyệt / HĐH có thể được giảm thiểu bằng cách sử dụng Thư viện điều chỉnh thời gian chạy theo Trình duyệt (như Sencha) 2. Khả năng tương thích trình duyệt không ảnh hưởng đến các phần mã "logic" như xác thực, các vấn đề tương thích thường xung quanh Kết xuất DOM / UI.
Shamit Verma

0

Tôi chỉ nghĩ về cùng một vấn đề. Tôi đã nghĩ đến việc sử dụng ANTLR để có được một cây cú pháp trừu tượng trong cả C # và javascript. Từ đó bạn sử dụng các máy đi bộ trên cây để áp dụng các hành động được chỉ định trong ngôn ngữ cho các đối tượng được xác nhận.

Vì vậy, sau đó bạn có thể lưu trữ một mô tả về xác nhận bắt buộc bất cứ nơi nào bạn muốn - có thể trong cơ sở dữ liệu.

Đây là cách tôi sẽ tiếp cận vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.