Câu hỏi này đã được giải quyết, ở một dạng hơi khác, ở độ dài, ở đây:
Xác thực RESTful
Nhưng điều này giải quyết nó từ phía máy chủ. Hãy xem xét điều này từ phía khách hàng. Tuy nhiên, trước khi chúng tôi làm điều đó, có một khúc dạo đầu quan trọng:
Tiền điện tử Javascript là vô vọng
Bài viết của Matasano về điều này rất nổi tiếng, nhưng những bài học trong đó khá quan trọng:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
Để tóm tắt:
- Một cuộc tấn công trung gian có thể thay thế một cách tầm thường mã số tiền điện tử của bạn bằng
<script>
function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
- Một cuộc tấn công giữa chừng là tầm thường đối với một trang phục vụ bất kỳ tài nguyên nào qua kết nối không có SSL.
- Khi bạn có SSL, bạn đang sử dụng tiền điện tử thực sự.
Và để thêm một hệ quả của riêng tôi:
- Một cuộc tấn công XSS thành công có thể dẫn đến việc kẻ tấn công thực thi mã trên trình duyệt của khách hàng của bạn, ngay cả khi bạn đang sử dụng SSL - vì vậy ngay cả khi bạn đã bị hỏng mọi thứ, mật mã trình duyệt của bạn vẫn có thể thất bại nếu kẻ tấn công của bạn tìm cách thực thi bất kỳ mã javascript nào trên trình duyệt của người khác.
Điều này làm cho rất nhiều lược đồ xác thực RESTful không thể hoặc ngớ ngẩn nếu bạn có ý định sử dụng máy khách JavaScript. Hãy nhìn xem!
Xác thực cơ bản HTTP
Đầu tiên và quan trọng nhất, HTTP Basic Auth. Các lược đồ đơn giản nhất: chỉ cần truyền tên và mật khẩu với mỗi yêu cầu.
Tất nhiên, điều này hoàn toàn yêu cầu SSL, bởi vì bạn đang chuyển một tên và mật khẩu được mã hóa Base64 (có thể đảo ngược) với mỗi yêu cầu. Bất cứ ai nghe trên dòng có thể trích xuất tên người dùng và mật khẩu một cách tầm thường. Hầu hết các đối số "Auth cơ bản là không an toàn" đến từ một nơi "Auth cơ bản trên HTTP" là một ý tưởng tồi tệ.
Trình duyệt cung cấp hỗ trợ HTTP Basic Auth tích hợp, nhưng nó xấu như tội lỗi và có lẽ bạn không nên sử dụng nó cho ứng dụng của mình. Tuy nhiên, cách khác là bỏ tên người dùng và mật khẩu trong JavaScript.
Đây là giải pháp RESTful nhất. Máy chủ không yêu cầu kiến thức về trạng thái nào và xác thực mọi tương tác riêng lẻ với người dùng. Một số người đam mê REST (chủ yếu là người rơm) nhấn mạnh rằng việc duy trì bất kỳ loại trạng thái nào là dị giáo và sẽ sùi bọt mép nếu bạn nghĩ đến bất kỳ phương pháp xác thực nào khác. Có những lợi ích về mặt lý thuyết cho loại tuân thủ tiêu chuẩn này - nó được Apache hỗ trợ - bạn có thể lưu trữ các đối tượng của mình dưới dạng các tệp trong các thư mục được bảo vệ bởi các tệp .htaccess nếu bạn muốn!
Các vấn đề ? Bạn đang lưu trữ trên máy khách tên người dùng và mật khẩu. Điều này mang lại cho evil.ru một vết nứt tốt hơn - ngay cả những lỗ hổng XSS cơ bản nhất cũng có thể dẫn đến việc khách hàng truyền tên người dùng và mật khẩu của mình vào một máy chủ xấu. Bạn có thể cố gắng giảm bớt rủi ro này bằng cách băm và muối mật khẩu, nhưng hãy nhớ: JavaScript Crypto là vô vọng . Bạn có thể giảm bớt rủi ro này bằng cách để nó hỗ trợ Auth cơ bản của Trình duyệt, nhưng .. xấu như tội lỗi, như đã đề cập trước đó.
Xác thực HTTP
Có thể xác thực Digest với jQuery không?
Một auth "an toàn" hơn, đây là một thách thức băm yêu cầu / phản hồi. Ngoại trừ JavaScript Crypto là vô vọng , vì vậy nó chỉ hoạt động trên SSL và bạn vẫn phải lưu tên người dùng và mật khẩu ở phía máy khách, làm cho nó phức tạp hơn HTTP Basic Auth nhưng không an toàn hơn .
Xác thực truy vấn với các tham số chữ ký bổ sung.
Một auth "an toàn" khác, trong đó bạn mã hóa các tham số của mình bằng dữ liệu nonce và time (để bảo vệ chống lại các cuộc tấn công lặp lại và thời gian) và gửi. Một trong những ví dụ tốt nhất về điều này là giao thức OAuth 1.0, theo như tôi biết, là một cách khá đáng kinh ngạc để thực hiện xác thực trên máy chủ REST.
http://tools.ietf.org/html/rfc5849
Ồ, nhưng không có bất kỳ ứng dụng khách OAuth 1.0 nào cho JavaScript. Tại sao?
JavaScript Crypto là vô vọng , hãy nhớ. JavaScript không thể tham gia OAuth 1.0 mà không có SSL và bạn vẫn phải lưu trữ tên người dùng và mật khẩu của khách hàng cục bộ - điều này đặt cùng loại với Digest Auth - nó phức tạp hơn HTTP Basic Auth nhưng nó không an toàn hơn .
Mã thông báo
Người dùng gửi tên người dùng và mật khẩu và đổi lại nhận được mã thông báo có thể được sử dụng để xác thực các yêu cầu.
Điều này an toàn hơn một chút so với HTTP Basic Auth, vì ngay khi giao dịch tên người dùng / mật khẩu hoàn tất, bạn có thể loại bỏ dữ liệu nhạy cảm. Nó cũng ít RESTful hơn, vì mã thông báo tạo thành "trạng thái" và làm cho việc triển khai máy chủ trở nên phức tạp hơn.
SSL vẫn
Tuy nhiên, điều khó khăn là bạn vẫn phải gửi tên người dùng và mật khẩu ban đầu đó để nhận mã thông báo. Thông tin nhạy cảm vẫn chạm vào JavaScript có thể thỏa hiệp của bạn.
Để bảo vệ thông tin đăng nhập của người dùng, bạn vẫn cần phải tránh những kẻ tấn công ra khỏi JavaScript của mình và bạn vẫn cần gửi tên người dùng và mật khẩu qua mạng. Yêu cầu SSL.
Hết hạn mã thông báo
Việc thực thi các chính sách mã thông báo như "hey, khi mã thông báo này đã tồn tại quá lâu, hãy loại bỏ nó và làm cho người dùng xác thực lại". hoặc "Tôi khá chắc chắn rằng địa chỉ IP duy nhất được phép sử dụng mã thông báo này là XXX.XXX.XXX.XXX
". Nhiều trong số các chính sách này là những ý tưởng khá tốt.
Đốt lửa
Tuy nhiên, sử dụng mã thông báo không có SSL vẫn dễ bị tấn công có tên là 'sidejacking': http://codebutler.github.io/firesheep/
Kẻ tấn công không nhận được thông tin đăng nhập của người dùng của bạn, nhưng họ vẫn có thể giả vờ là người dùng của bạn, điều này có thể khá tệ.
tl; dr: Gửi mã thông báo không được mã hóa qua dây có nghĩa là kẻ tấn công có thể dễ dàng lấy mã thông báo đó và giả vờ là người dùng của bạn. FireSheep là một chương trình làm cho điều này rất dễ dàng.
Một khu vực riêng biệt, an toàn hơn
Ứng dụng mà bạn đang chạy càng lớn thì càng khó đảm bảo rằng họ sẽ không thể tiêm một số mã thay đổi cách bạn xử lý dữ liệu nhạy cảm. Bạn có hoàn toàn tin tưởng CDN của bạn? Các nhà quảng cáo của bạn? Mã cơ sở của riêng bạn?
Phổ biến cho các chi tiết thẻ tín dụng và ít phổ biến hơn cho tên người dùng và mật khẩu - một số người triển khai giữ 'mục nhập dữ liệu nhạy cảm' trên một trang riêng biệt với phần còn lại của ứng dụng của họ, một trang có thể được kiểm soát chặt chẽ và khóa chặt nhất có thể, tốt nhất là một trang Rất khó để lừa đảo người dùng với.
Cookie (chỉ có nghĩa là mã thông báo)
Có thể (và phổ biến) để đặt mã thông báo xác thực vào cookie. Điều này không thay đổi bất kỳ thuộc tính nào của auth với mã thông báo, đó là một điều tiện lợi. Tất cả các đối số trước đây vẫn được áp dụng.
Phiên (vẫn chỉ có nghĩa là mã thông báo)
Phiên Auth chỉ là xác thực mã thông báo, nhưng với một vài khác biệt khiến nó có vẻ như là một điều hơi khác:
- Người dùng bắt đầu với mã thông báo chưa được xác thực.
- Phần phụ trợ duy trì một đối tượng 'trạng thái' được gắn với mã thông báo của người dùng.
- Mã thông báo được cung cấp trong cookie.
- Môi trường ứng dụng trừu tượng hóa các chi tiết từ bạn.
Mặc dù vậy, bên cạnh đó, nó không khác gì Token Auth, thực sự.
Điều này thậm chí còn đi xa hơn từ việc triển khai RESTful - với các đối tượng trạng thái bạn sẽ tiến xa hơn và đi sâu hơn vào đường dẫn của RPC đơn giản trên máy chủ trạng thái.
OAuth 2.0
OAuth 2.0 xem xét vấn đề "Làm thế nào để Phần mềm A cấp cho Phần mềm B quyền truy cập vào dữ liệu của Người dùng X mà Phần mềm B không có quyền truy cập vào thông tin đăng nhập của Người dùng X".
Việc triển khai thực sự chỉ là một cách tiêu chuẩn để người dùng nhận được mã thông báo và sau đó cho dịch vụ bên thứ ba chuyển "yep, người dùng này và mã thông báo này khớp và bạn có thể nhận được một số dữ liệu của họ từ chúng tôi ngay bây giờ."
Về cơ bản, mặc dù, OAuth 2.0 chỉ là một giao thức mã thông báo. Nó thể hiện các thuộc tính giống như các giao thức mã thông báo khác - bạn vẫn cần SSL để bảo vệ các mã thông báo đó - nó chỉ thay đổi cách tạo ra các mã thông báo đó.
Có hai cách mà OAuth 2.0 có thể giúp bạn:
- Cung cấp xác thực / thông tin cho người khác
- Nhận xác thực / thông tin từ người khác
Nhưng khi nói đến nó, bạn chỉ ... sử dụng mã thông báo.
Quay lại câu hỏi của bạn
Vì vậy, câu hỏi mà bạn đang hỏi là "tôi có nên lưu trữ mã thông báo của mình trong cookie và để quản lý phiên tự động của môi trường của tôi xử lý các chi tiết hay tôi nên lưu trữ mã thông báo của mình trong Javascript và tự xử lý các chi tiết đó?"
Và câu trả lời là: làm bất cứ điều gì khiến bạn hạnh phúc .
Tuy nhiên, điều về quản lý phiên tự động là có rất nhiều điều kỳ diệu xảy ra đằng sau hậu trường cho bạn. Thường thì việc kiểm soát những chi tiết đó sẽ tốt hơn.
Tôi 21 tuổi nên SSL là có
Câu trả lời khác là: Sử dụng https cho mọi thứ hoặc các nhóm sẽ đánh cắp mật khẩu và mã thông báo của người dùng của bạn.