JavaScript: xác thực phía máy khách so với phía máy chủ


179

Cái nào tốt hơn để làm xác nhận phía máy khách hoặc phía máy chủ?

Trong tình hình của chúng tôi, chúng tôi đang sử dụng

  • jQuery và MVC.
  • Dữ liệu JSON để chuyển giữa Chế độ xem và Trình điều khiển của chúng tôi.

Rất nhiều xác nhận tôi làm là xác nhận dữ liệu khi người dùng nhập nó. Ví dụ: tôi sử dụng keypresssự kiện này để ngăn các chữ cái trong hộp văn bản, đặt số lượng ký tự tối đa và một số có trong một phạm vi.

Tôi đoán câu hỏi tốt hơn sẽ là, Có bất kỳ lợi ích nào khi thực hiện xác nhận phía máy chủ so với phía máy khách không?


Tuyệt vời trả lời tất cả mọi người. Trang web mà chúng tôi có được bảo vệ bằng mật khẩu và cho một cơ sở người dùng nhỏ (<50). Nếu họ không chạy JavaScript, chúng tôi sẽ gửi ninja. Nhưng nếu chúng tôi thiết kế một trang web cho mọi người thì tôi đồng ý thực hiện xác nhận ở cả hai bên.


2
javascript có thể bị vô hiệu hóa
Enrico Murru

Không có cách nào chắc chắn để chặn người dùng vô hiệu hóa JavaScript. Nếu người dùng đến trang của bạn có bật JS, và sau đó vô hiệu hóa nó, bạn không thể làm gì được. (OK, bạn có thể sử dụng JS để thực hiện kiểm soát gửi, để nó sẽ ngừng hoạt động trong kịch bản này, nhưng điều này có thể được bỏ qua giống như mọi thứ khác.)
Stewart

Câu trả lời:


347

Như những người khác đã nói, bạn nên làm cả hai. Đây là lý do tại sao:

Phía khách hàng

Bạn muốn xác thực đầu vào ở phía khách hàng trước vì bạn có thể cung cấp phản hồi tốt hơn cho người dùng trung bình . Ví dụ: nếu họ nhập địa chỉ email không hợp lệ và chuyển sang trường tiếp theo, bạn có thể hiển thị thông báo lỗi ngay lập tức. Bằng cách đó, người dùng có thể sửa mọi trường trước khi họ gửi biểu mẫu.

Nếu bạn chỉ xác nhận trên máy chủ, họ phải gửi biểu mẫu, nhận thông báo lỗi và cố gắng tìm ra vấn đề.

(Nỗi đau này có thể được giảm bớt bằng cách máy chủ kết xuất lại biểu mẫu với đầu vào ban đầu của người dùng được điền vào, nhưng xác thực phía máy khách vẫn nhanh hơn.)

Phía máy chủ

Bạn muốn xác thực về phía máy chủ vì bạn có thể bảo vệ chống lại người dùng độc hại , những người có thể dễ dàng bỏ qua JavaScript của bạn và gửi đầu vào nguy hiểm cho máy chủ.

Sẽ rất nguy hiểm khi tin tưởng UI của bạn. Họ không chỉ có thể lạm dụng UI của bạn, mà họ có thể không sử dụng UI của bạn, hoặc thậm chí là một trình duyệt . Điều gì xảy ra nếu người dùng chỉnh sửa URL theo cách thủ công hoặc chạy Javascript của riêng họ hoặc điều chỉnh các yêu cầu HTTP của họ bằng một công cụ khác? Điều gì xảy ra nếu họ gửi các yêu cầu HTTP tùy chỉnh từ curlhoặc từ một tập lệnh chẳng hạn?

( Đây không phải là lý thuyết; ví dụ: tôi đã làm việc trên một công cụ tìm kiếm du lịch đã gửi lại tìm kiếm của người dùng cho nhiều hãng hàng không đối tác, công ty xe buýt, v.v., bằng cách gửi POSTyêu cầu như thể người dùng đã điền vào mẫu tìm kiếm của mỗi công ty, sau đó tập hợp và sắp xếp tất cả các kết quả. Mẫu JS của các công ty đó chưa bao giờ được thực thi và điều quan trọng đối với chúng tôi là họ cung cấp các thông báo lỗi trong HTML được trả lại. Tất nhiên, một API sẽ rất tốt, nhưng đây là điều chúng tôi phải làm. )

Không cho phép điều đó không chỉ ngây thơ từ quan điểm bảo mật, mà còn không chuẩn: khách hàng nên được phép gửi HTTP bằng bất cứ phương tiện nào họ muốn và bạn nên trả lời chính xác. Điều đó bao gồm xác nhận.

Xác thực phía máy chủ cũng rất quan trọng đối với khả năng tương thích - không phải tất cả người dùng, ngay cả khi họ đang sử dụng trình duyệt, sẽ bật JavaScript.

Phụ lục - Tháng 12 năm 2016

Có một số xác nhận thậm chí không thể được thực hiện đúng trong mã ứng dụng phía máy chủ và hoàn toàn không thể trong mã phía máy khách , vì chúng phụ thuộc vào trạng thái hiện tại của cơ sở dữ liệu. Ví dụ: "không có ai khác đã đăng ký tên người dùng đó" hoặc "bài đăng blog bạn đang bình luận vẫn tồn tại" hoặc "không có đặt chỗ hiện tại trùng với ngày bạn yêu cầu" hoặc "số dư tài khoản của bạn vẫn đủ để chi trả cho giao dịch mua đó . " Chỉ cơ sở dữ liệu có thể xác thực dữ liệu đáng tin cậy phụ thuộc vào dữ liệu liên quan. Các nhà phát triển thường xuyên làm hỏng việc này , nhưng PostgreSQL cung cấp một số giải pháp tốt .


30
Đây phải là câu trả lời được chấp nhận, thậm chí 6 năm sau: P
Jacob McKay

17
Có, tôi muốn đợi gần 10 năm để chắc chắn.
Brad8118

2
@kidmosey "đó là một sự vi phạm rõ ràng các nguyên tắc DRY" Có, điều đó có nghĩa là nỗi đau cho các lập trình viên như chúng tôi. Nhưng hãy tưởng tượng một hình thức đăng ký. Nếu sao chép kiến ​​thức "một địa chỉ email phải chứa @" trong mã máy khách có nghĩa là người dùng nhận được phản hồi nhanh hơn và nhiều người trong số họ đăng ký, dẫn đến doanh thu thêm 100 nghìn đô la mỗi năm, nhiều hơn chi trả cho chi phí bảo trì thêm. DRY là một nguyên tắc rất tốt, nhưng nó không phải là sự cân nhắc duy nhất. Chất lượng mã thực sự được đo lường ở mức độ phục vụ người dùng và tổ chức trong phân tích chi phí / lợi ích.
Nathan Long

1
@ArunRaaj Có, và bạn sẽ nắm bắt được hầu hết các vấn đề theo cách đó, nhưng nó không đáng tin cậy 100%. Nếu hai người dùng điền vào biểu mẫu cùng một lúc, cả hai có thể được cho biết đó user1là tên người dùng có sẵn. Khi họ gửi, cả hai sẽ có cùng tên người dùng trừ khi bạn kiểm tra lại phía máy chủ. Và ngay cả một kiểm tra trong mã ứng dụng máy chủ cũng có thể có cùng một vấn đề: hai yêu cầu đến, yêu cầu đầu tiên kiểm tra cơ sở dữ liệu và được thông báo OK, lần thứ hai kiểm tra cơ sở dữ liệu và được thông báo, lần đầu tiên được lưu, lần thứ hai được lưu như một bản sao Chỉ một ràng buộc duy nhất db đảm bảo tính duy nhất.
Nathan Long

1
@NathanLong Xác thực trên dữ liệu nhạy cảm với điều kiện cuộc đua không khó hiểu vì câu này làm cho chúng có âm thanh. Thật khó để làm đúng, nhưng tạo một cơ chế bảo lưu sử dụng tài nguyên được đồng bộ hóa để yêu cầu. Vì vậy, nếu người dùng gõ "usernameA", kiểm tra tính duy nhất trên máy chủ không cho phép nhiều cuộc gọi đồng thời để kiểm tra nếu duy nhất; nếu là duy nhất, cũng dự trữ nó với mã thông báo tạm thời được gán cho máy khách cũng được phát hành nếu tên người dùng khác được kiểm tra bởi cùng một ID phiên. Mã thông báo sẽ hết hạn sau một thời gian hợp lý. Ví dụ: Dự trữ chỗ ngồi TicketMaster.
Elaskanator

79

Có, xác nhận phía khách hàng có thể được bỏ qua hoàn toàn, luôn luôn. Bạn cần thực hiện cả hai, phía máy khách để cung cấp trải nghiệm người dùng tốt hơn và phía máy chủ để đảm bảo rằng đầu vào bạn nhận được thực sự được xác thực và không chỉ được xác nhận bởi máy khách.


43

Tôi sẽ lặp lại nó, bởi vì nó khá quan trọng:

Luôn xác nhận trên máy chủ

và thêm JavaScript để đáp ứng người dùng.


31

Lợi ích của việc xác thực phía máy chủ so với xác thực phía máy khách là xác thực phía máy khách có thể được bỏ qua / thao tác:

  • Người dùng cuối có thể tắt javascript
  • Dữ liệu có thể được gửi trực tiếp đến máy chủ của bạn bởi một người thậm chí không sử dụng trang web của bạn, với một ứng dụng tùy chỉnh được thiết kế để làm như vậy
  • Một lỗi Javascript trên trang của bạn (gây ra bởi bất kỳ số lượng điều) có thể dẫn đến một số, nhưng không phải tất cả, về việc xác thực của bạn đang chạy

Tóm lại - luôn luôn, luôn xác nhận phía máy chủ và sau đó xem xét xác thực phía máy khách như là một "bổ sung" bổ sung để nâng cao trải nghiệm người dùng cuối.


18

Bạn phải luôn xác nhận trên máy chủ.

Ngoài ra có xác nhận trên máy khách là tốt cho người dùng, nhưng hoàn toàn không an toàn.


9

Vâng, tôi vẫn tìm thấy một số phòng để trả lời.

Ngoài câu trả lời từ Rob và Nathan, tôi sẽ nói thêm rằng việc xác nhận phía khách hàng có vấn đề. Khi bạn đang áp dụng xác nhận trên biểu mẫu web của mình, bạn phải tuân theo các nguyên tắc sau:

Phía khách hàng

  1. Phải sử dụng xác nhận phía khách hàng để lọc các yêu cầu chính hãng đến từ người dùng chính hãng tại trang web của bạn.
  2. Xác nhận phía máy khách nên được sử dụng để giảm các lỗi có thể xảy ra trong quá trình xử lý phía máy chủ.
  3. Xác thực phía máy khách nên được sử dụng để giảm thiểu các chuyến đi khứ hồi phía máy chủ để bạn tiết kiệm băng thông và các yêu cầu cho mỗi người dùng.

Phía máy chủ

  1. Bạn KHÔNG NÊN cho rằng việc xác thực thành công ở phía khách hàng là hoàn hảo 100%. Không có vấn đề ngay cả khi nó phục vụ ít hơn 50 người dùng. Bạn không bao giờ biết người dùng / người dùng nào của mình biến thành "kẻ xấu" và thực hiện một số hoạt động có hại khi biết rằng bạn không có xác nhận hợp lệ.
  2. Ngay cả khi nó hoàn hảo về mặt xác thực địa chỉ email, số điện thoại hoặc kiểm tra một số đầu vào hợp lệ, nó có thể chứa dữ liệu rất có hại. Mà cần phải được lọc ở phía máy chủ cho dù nó đúng hay không chính xác.
  3. Nếu xác thực phía máy khách bị bỏ qua, xác thực phía máy chủ của bạn sẽ giải cứu bạn khỏi mọi thiệt hại tiềm tàng đối với việc xử lý phía máy chủ của bạn. Trong thời gian gần đây, chúng tôi đã nghe rất nhiều câu chuyện về SQL Tiêm và các loại kỹ thuật khác có thể được áp dụng để đạt được một số lợi ích xấu.

Cả hai loại xác nhận đóng vai trò quan trọng trong phạm vi tương ứng của chúng nhưng mạnh nhất là phía máy chủ. Nếu bạn nhận được 10 nghìn người dùng tại một thời điểm thì chắc chắn bạn sẽ kết thúc việc lọc số lượng yêu cầu đến máy chủ web của mình. Nếu bạn thấy có một lỗi duy nhất như địa chỉ email không hợp lệ thì họ sẽ gửi lại biểu mẫu và yêu cầu người dùng của bạn sửa nó, điều này chắc chắn sẽ ăn tài nguyên và băng thông máy chủ của bạn. Vì vậy, tốt hơn bạn áp dụng xác nhận javascript. Nếu javascript bị vô hiệu hóa thì xác thực phía máy chủ của bạn sẽ được giải cứu và tôi cá rằng chỉ một số người dùng có thể vô tình vô hiệu hóa nó vì 99,99% trang web sử dụng javascript và mặc định đã được bật trong tất cả các trình duyệt hiện đại.


Tôi đã thấy mọi người bỏ bê để bảo vệ chống lại việc tiêm mã hoàn toàn, đừng bận tâm chỉ làm điều đó ở phía khách hàng. Và không có tài liệu tham khảo nào về việc tiêm mã hoàn tất mà không có liên kết đến đây: xkcd.com/327 :)
Stewart

8

Bạn có thể thực hiện xác thực phía Máy chủ và gửi lại một đối tượng JSON với kết quả xác thực cho từng trường, giữ cho Javascript của máy khách ở mức tối thiểu (chỉ hiển thị kết quả) và vẫn có trải nghiệm thân thiện với người dùng mà không phải lặp lại trên cả máy khách và máy chủ.


3
Thân thiện với người dùng? Có lẽ. Hầu như tức thời và bơ mịn? Chắc là không.
tăng gấp bốn lần

4

Phía khách hàng nên sử dụng xác thực cơ bản thông qua các loại đầu vào HTML5các thuộc tính mẫu và vì chúng chỉ được sử dụng để cải tiến lũy tiến cho trải nghiệm người dùng tốt hơn (Ngay cả khi chúng không được hỗ trợ trên <IE9 và safari, nhưng chúng tôi không dựa vào chúng). Nhưng xác nhận chính sẽ xảy ra ở phía máy chủ ..


"Nhưng việc xác nhận chính sẽ xảy ra ở phía máy chủ." Không nên, phải.
Stewart


2

JavaScript có thể được sửa đổi trong thời gian chạy.

Tôi đề xuất một mô hình tạo cấu trúc xác nhận trên máy chủ và chia sẻ điều này với máy khách.

Bạn sẽ cần logic xác thực riêng biệt ở cả hai đầu, ví dụ:

"required"thuộc tính ở inputsphía khách hàng

field.length > 0 phía máy chủ.

Nhưng sử dụng cùng một đặc tả xác nhận sẽ loại bỏ một số dư thừa (và sai lầm) của việc xác thực phản chiếu ở cả hai đầu.


2

Xác thực dữ liệu phía máy khách có thể hữu ích cho trải nghiệm người dùng tốt hơn: ví dụ: tôi là người dùng nhập sai địa chỉ email của mình, không nên đợi đến khi yêu cầu của anh ta được máy chủ từ xa xử lý để tìm hiểu về lỗi đánh máy anh ta đã làm.

Tuy nhiên, vì kẻ tấn công có thể bỏ qua xác thực phía máy khách (và thậm chí có thể không sử dụng trình duyệt), nên phải xác thực phía máy chủ và phải là cổng thực sự để bảo vệ phụ trợ của bạn khỏi người dùng bất chính.


1

Tôi bắt gặp một liên kết thú vị tạo ra sự khác biệt giữa các lỗi ngẫu nhiên, có hệ thống, ngẫu nhiên.

Client-Side validationphù hợp hoàn hảo để ngăn ngừa lỗi thô và ngẫu nhiên. Điển hình là độ dài tối đa cho kết cấu và đầu vào. Không bắt chước quy tắc xác thực phía máy chủ; cung cấp tổng quy tắc xác thực ngón tay cái của riêng bạn (ví dụ: 200 ký tự ở phía máy khách; ở phía nmáy chủ được quy định bởi một quy tắc kinh doanh mạnh).

Server-side validationphù hợp hoàn hảo để ngăn ngừa lỗi hệ thống; nó sẽ thực thi các quy tắc kinh doanh.

Trong một dự án tôi tham gia, việc xác thực được thực hiện trên máy chủ thông qua các yêu cầu ajax. Trên máy khách tôi hiển thị thông báo lỗi tương ứng.

Đọc thêm: lỗi tổng, hệ thống, ngẫu nhiên:

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


-2

Nếu bạn đang thực hiện xác nhận ánh sáng, tốt nhất là thực hiện nó trên máy khách. Nó sẽ lưu lưu lượng mạng sẽ giúp máy chủ của bạn hoạt động tốt hơn. Nếu việc xác thực phức tạp liên quan đến việc lấy dữ liệu từ cơ sở dữ liệu hoặc thứ gì đó, như mật khẩu, thì tốt nhất nên thực hiện trên máy chủ nơi dữ liệu có thể được kiểm tra an toàn.


2
Những gì bạn đang hấp dẫn không phải là ý tưởng tốt nhất. Người dùng luôn có thể bỏ qua xác thực phía máy khách và gửi bất cứ điều gì họ muốn đến cơ sở dữ liệu.
kremuwa
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.