Xác thực kiến ​​trúc sạch trong miền và lớp dữ liệu bền vững?


12

Tôi đang nghiên cứu về sạch sẽ và kết quả là tôi đang suy nghĩ lại rất nhiều về cách tôi thiết kế và viết phần mềm.

Tuy nhiên, tôi vẫn đang vật lộn với các quy tắc kinh doanh như "lưu các bản cập nhật cho một số mặt hàng, tải đầu tiên Tất cả danh sách các mặt hàng tôi có quyền xem / chỉnh sửa, v.v., xác nhận rằng mặt hàng này có trong danh sách, và rằng danh mục mặt hàng hiện không bị khóa khi sử dụng, (và các quy tắc khác, v.v.) ".. vì đó là quy tắc kinh doanh (phức tạp nhưng không điển hình) và do đó nên được xử lý trong miền ứng dụng thay vì đẩy logic nghiệp vụ vào lớp db / kiên trì.

Tuy nhiên, đối với tôi, để kiểm tra hiệu quả các điều kiện này, nó thường sẽ được xử lý tốt nhất với truy vấn db được tạo thủ công, thay vì tải tất cả dữ liệu vào miền ứng dụng ...

Nếu không tối ưu hóa sớm, cách tiếp cận được đề xuất hoặc một số bài viết của chú Bob liên quan đến câu hỏi này là gì? Hoặc anh ta sẽ nói "xác nhận trong miền cho đến khi nó trở thành một vấn đề" ??

Tôi thực sự đang vật lộn để tìm bất kỳ ví dụ / mẫu tốt cho bất cứ điều gì khác ngoài các trường hợp sử dụng cơ bản nhất.

Cập nhật:

Hi tất cả, cảm ơn đã trả lời. Tôi nên rõ ràng hơn, tôi đã viết phần mềm (chủ yếu là ứng dụng web) trong một thời gian dài và chắc chắn đã có kinh nghiệm và đồng ý với tất cả các chủ đề mà bạn mô tả chung (xác thực bởi phụ trợ, nói chung là không tin tưởng dữ liệu khách hàng Tuy nhiên, chỉ theo đuổi hiệu quả thô khi có yêu cầu, thừa nhận điểm mạnh của các công cụ db khi có sẵn, v.v.) và đã trải qua vòng đời học tập của nhà phát triển về "ném tất cả cùng nhau" để "xây dựng bộ điều khiển chất béo khổng lồ với các xu hướng mã của ứng dụng N-tiers" , và bây giờ thực sự thích và nghiên cứu phong cách trách nhiệm sạch sẽ / duy nhất, v.v., về cơ bản là kết quả của một vài dự án gần đây đã phát triển thành các quy tắc kinh doanh khá phân tán và phân tán rộng rãi khi các dự án phát triển và yêu cầu khách hàng tiếp tục được đưa ra.

Đặc biệt, tôi nhìn vào kiến trúc phong cách sạch trong bối cảnh xây dựng apis REST cho khách hàng phải đối mặt với cũng như chức năng nội bộ sử dụng, nơi có nhiều quy tắc kinh doanh có thể là nhiều phức tạp hơn về cơ bản tất cả các ví dụ mà bạn nhìn thấy trên mạng (thậm chí bởi chính những người kiến ​​trúc Clean / Hex).

Vì vậy, tôi đoán rằng tôi đã thực sự hỏi (và không nói rõ) về việc Clean và một api REST sẽ ngồi cùng nhau như thế nào, nơi hầu hết các công cụ MVC mà bạn thấy ngày nay có trình xác nhận yêu cầu đến (ví dụ thư viện FluentValidation trong .NET), nhưng có nhiều Các quy tắc "xác thực" của tôi không quá nhiều "đây có phải là một chuỗi dưới 50 ký tự" nhưng nhiều hơn "người dùng này có thể gọi người dùng / người tương tác này thực hiện thao tác này trên bộ sưu tập dữ liệu này do một số đối tượng liên quan hiện đang bị Nhóm X khóa không cho đến cuối tháng, v.v. "... những loại xác nhận có liên quan sâu sắc trong đó rất nhiều đối tượng miền doanh nghiệp và quy tắc miền được áp dụng.

Tôi có nên chuyển các quy tắc đó thành một loại đối tượng Trình xác thực cụ thể để đi kèm với mỗi trình tương tác usecase (lấy cảm hứng từ dự án FluentValidator nhưng có liên quan đến logic kinh doanh và truy cập dữ liệu hơn), tôi có nên xử lý xác thực phần nào như Cổng không đặt các xác nhận đó vào một cổng (mà tôi nghĩ là sai), v.v.

Để tham khảo, tôi sẽ giới thiệu một số bài viết như thế này , nhưng Mattia không thảo luận nhiều về xác nhận.

Nhưng tôi đoán câu trả lời ngắn cho câu hỏi của tôi giống như câu trả lời mà tôi đã chấp nhận: "Nó không bao giờ dễ dàng, và nó phụ thuộc".


2
Thường có một sự khác biệt giữa "chính xác" và "thực tế". Đưa ra lựa chọn, bạn thích cái nào hơn?
Robert Harvey

"tải tất cả danh sách các mặt hàng" không giống như một quy tắc kinh doanh, nó dường như đang đi sâu vào chi tiết thực hiện. Nếu bạn có thể đáp ứng quy tắc bằng cách sử dụng truy vấn db, mà không tải bất cứ điều gì, tại sao quy tắc lại nói "tải"?
Ngừng làm hại Monica

Câu trả lời:


31

Xác thực nhập dữ liệu là một trong những điều mà mọi người bắt đầu cố gắng làm cho nó hoàn toàn trong sạch và (nếu họ thông minh về điều đó) cuối cùng sẽ bỏ cuộc, bởi vì có rất nhiều mối quan tâm cạnh tranh.

  • Lớp UI phải thực hiện một số hình thức xác nhận ngay trên trang / biểu mẫu của khách hàng để cung cấp phản hồi thời gian thực cho người dùng. Nếu không, người dùng dành rất nhiều thời gian chờ phản hồi trong khi một giao dịch được đăng trên mạng.

  • Vì máy khách thường chạy trên một máy không tin cậy (ví dụ: trong gần như tất cả các ứng dụng web), các thói quen xác thực này phải được thực hiện lại phía máy chủ nơi mã được tin cậy.

  • Một số hình thức xác nhận được ngầm định do các ràng buộc đầu vào; ví dụ, một hộp văn bản có thể chỉ cho phép nhập số. Điều này có nghĩa là bạn có thể không có "nó có phải là số không?" trình xác nhận trên trang, nhưng bạn vẫn sẽ cần một trình duyệt ở mặt sau, ở đâu đó, vì các ràng buộc UI có thể được bỏ qua (ví dụ: bằng cách vô hiệu hóa Javascript).

  • Lớp UI phải thực hiện một số hình thức xác nhận theo chu vi dịch vụ (ví dụ mã phía máy chủ trong ứng dụng web) để bảo vệ hệ thống chống lại các cuộc tấn công tiêm chích hoặc các hình thức nhập dữ liệu độc hại khác. Đôi khi việc xác thực này thậm chí không nằm trong cơ sở mã của bạn, ví dụ: xác thực yêu cầu ASP.NET .

  • Lớp UI phải thực hiện một số hình thức xác nhận chỉ để chuyển đổi dữ liệu do người dùng nhập vào định dạng mà lớp doanh nghiệp có thể hiểu được; ví dụ: nó phải biến chuỗi "26/11/2017" thành đối tượng DateTime theo múi giờ thích hợp.

  • Về mặt lý thuyết, lớp nghiệp vụ nên thực hiện hầu hết các hình thức xác nhận vì chúng thuộc về lớp nghiệp vụ.

  • Một số hình thức xác nhận hiệu quả hơn ở lớp cơ sở dữ liệu, đặc biệt là khi cần kiểm tra tính toàn vẹn tham chiếu (ví dụ: để đảm bảo rằng mã trạng thái nằm trong danh sách 50 trạng thái hợp lệ).

  • Một số hình thức xác nhận phải xảy ra trong bối cảnh giao dịch cơ sở dữ liệu do lo ngại đồng thời, ví dụ: bảo lưu tên người dùng duy nhất phải là nguyên tử để một số người dùng khác không lấy nó trong khi bạn đang xử lý.

  • Một số hình thức xác nhận chỉ có thể được thực hiện bởi các dịch vụ của bên thứ ba, ví dụ như khi xác thực rằng mã bưu chính và tên thành phố đi cùng nhau.

  • Trong toàn hệ thống, kiểm tra null và kiểm tra chuyển đổi dữ liệu có thể xảy ra ở nhiều lớp, để đảm bảo các chế độ thất bại hợp lý khi có lỗi mã.

Tôi đã thấy một số nhà phát triển cố gắng mã hóa tất cả các quy tắc xác thực trong lớp nghiệp vụ và sau đó các lớp khác gọi nó để trích xuất các quy tắc kinh doanh và xây dựng lại xác thực ở một lớp khác. Về lý thuyết, điều này sẽ rất tuyệt vì bạn kết thúc với một nguồn sự thật duy nhất. Nhưng tôi chưa bao giờ, đã từng thấy cách tiếp cận này làm bất cứ điều gì khác ngoài việc làm phức tạp hóa giải pháp và nó thường kết thúc rất tệ.

Vì vậy, nếu bạn đang tự giết mình khi cố gắng tìm ra mã xác thực của mình đi đâu, hãy lưu ý - trong một giải pháp thực tế cho ngay cả một vấn đề phức tạp vừa phải, mã xác thực sẽ kết thúc ở một vài nơi.


Nếu bạn cho rằng UI của bạn quản lý tất cả phản hồi của người dùng, bạn chỉ có thể đẩy hầu hết kiểm tra xác thực trong cơ sở dữ liệu và chỉ giữ những gì bạn không thể làm trong đó ở lớp doanh nghiệp. Vấn đề phát sinh nếu bạn thiết kế API phụ trợ đầy đủ với khắc phục sự cố thông báo rất khó hiểu.
Walfrat

2

Xác nhận là một phần của lớp kinh doanh.

Vấn đề là: logic kinh doanh trong DAO sẽ làm mất hiệu lực khái niệm về DAO. Để thực hiện xác nhận ở bất kỳ lớp nào cao hơn sẽ dẫn đến xác thực dự phòng nếu bạn gọi các hoạt động kinh doanh từ một usecase khác.

Có thể bạn đánh giá một số bảo mật trong giao diện người dùng. Nhưng đó là tùy chọn vì các đối tượng miền được bảo mật sẽ thực hiện công việc quan trọng. Trong giao diện người dùng sẽ làm cho các Thành phần hiển thị hoặc vô hình tùy thuộc vào quyền mà người dùng đã đăng nhập hiện tại có. Nhưng đây chỉ là một phần của trải nghiệm người dùng. Bạn không muốn người dùng gặp phải các trường hợp ngoại lệ về bảo mật mỗi khi anh ta cố gắng thực hiện một hành động mà anh ta không được phép thực hiện.


2

Bạn có thể muốn kiểm tra quan điểm của mình về việc ai đang thực hiện xác nhận hợp lệ. Đây có phải là DB không, nơi bạn biết bạn đang làm việc với DB? Hoặc đó là một dịch vụ (điều đó được hỗ trợ và kiểm soát bởi các hoạt động DB). Trong dự án của tôi, mọi gốc tổng hợp có một danh sách các nhóm có thể đọc nó và một danh sách các sửa đổi. Khi mã tìm kiếm một gốc cụ thể hoặc một danh sách các gốc mà người dùng có thể nhìn thấy, tất cả các chi tiết được ẩn đằng sau một dịch vụ lấy id người dùng và các phần bổ sung của bối cảnh tìm kiếm như gạch bắt đầu với ốp tường. Mã không quan tâm rằng DB thực hiện kiểm tra tồn tại để xem các nhóm người dùng có tồn tại trong các nhóm của độc giả hay không. Nó chỉ mong đợi một danh sách có hoặc không có nội dung dựa trên những gì dịch vụ, được xác định chỉ bằng hợp đồng, cung cấp.

Điều này áp dụng tất cả các lớp. Tính đồng nhất của xác nhận là chìa khóa. Đặt càng nhiều xác nhận của bạn trong miền càng tốt. Trả lại các ràng buộc với api của bạn. Tôi cuối cùng không nghĩ đến các ràng buộc đến từ thư viện X hoặc bộ lưu trữ Z, mà là từ dịch vụ.


0

Nếu một số logic xác thực được thể hiện đơn giản và rõ ràng nhất dưới dạng truy vấn cơ sở dữ liệu, thì hãy tiếp tục, bạn có câu trả lời của mình. Nhưng hiệu quả chỉ nên là mối quan tâm nếu bạn có vấn đề về hiệu suất đã biết, nếu không thì đó là tối ưu hóa sớm.

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.