Có rất nhiều câu hỏi được đặt ra ở đây, và dường như mặc dù các câu hỏi được đặt ra trong bối cảnh của Node và Passport.js, các câu hỏi thực sự liên quan đến quy trình làm việc hơn là cách thực hiện điều này với một công nghệ cụ thể.
Hãy sử dụng thiết lập ví dụ @Keith, sửa đổi một chút để tăng cường bảo mật:
- Máy chủ web
https://example.com
phục vụ một ứng dụng khách Javascript duy nhất
- Dịch vụ web RESTful tại
https://example.com/api
cung cấp hỗ trợ máy chủ cho ứng dụng khách phong phú
- Máy chủ được triển khai trong Node và Passport.js.
- Máy chủ có cơ sở dữ liệu (bất kỳ loại nào) với bảng "người dùng".
- Tên người dùng / mật khẩu và Facebook Connect được cung cấp dưới dạng tùy chọn xác thực
- Máy khách phong phú biến các yêu cầu REST thành
https://example.com/api
- Có thể có các khách hàng khác (ví dụ: ứng dụng điện thoại) sử dụng dịch vụ web tại
https://example.com/api
nhưng không biết về máy chủ web tại https://example.com
.
Lưu ý rằng tôi đang sử dụng HTTP an toàn. Theo ý kiến của tôi, điều này là bắt buộc đối với bất kỳ dịch vụ nào có sẵn ở dạng mở, vì thông tin nhạy cảm như mật khẩu và mã thông báo ủy quyền đang truyền giữa máy khách và máy chủ.
Xác thực tên người dùng / mật khẩu
Trước tiên hãy xem cách xác thực cũ đơn giản hoạt động.
- Người dùng kết nối với
https://example.com
- Máy chủ phục vụ một ứng dụng Javascript phong phú hiển thị trang ban đầu. Ở đâu đó trong trang có một hình thức đăng nhập.
- Nhiều phần của ứng dụng một trang này chưa được điền dữ liệu do người dùng không đăng nhập. Tất cả các phần này có trình nghe sự kiện trong sự kiện "đăng nhập". Tất cả điều này là công cụ phía khách hàng, máy chủ không biết về những sự kiện này.
- Người dùng nhập thông tin đăng nhập và mật khẩu của mình và nhấn nút gửi, điều này kích hoạt trình xử lý Javascript để ghi lại tên người dùng và mật khẩu trong các biến phía máy khách. Sau đó, trình xử lý này kích hoạt sự kiện "đăng nhập". Một lần nữa, đây là tất cả hành động phía khách hàng, thông tin đăng nhập chưa được gửi đến máy chủ .
- Người nghe của sự kiện "đăng nhập" được gọi. Mỗi trong số này hiện cần gửi một hoặc nhiều yêu cầu tới API RESTful tại
https://example.com/api
để lấy dữ liệu cụ thể của người dùng để hiển thị trên trang. Mỗi yêu cầu họ gửi đến dịch vụ web sẽ bao gồm tên người dùng và mật khẩu, có thể dưới dạng xác thực HTTP Basic , vì dịch vụ là RESTful không được phép duy trì trạng thái máy khách từ yêu cầu này sang yêu cầu tiếp theo. Vì dịch vụ web trên HTTP an toàn, mật khẩu được mã hóa an toàn trong quá trình vận chuyển.
- Dịch vụ web
https://example.com/api
nhận được một loạt các yêu cầu riêng lẻ, mỗi yêu cầu có thông tin xác thực. Tên người dùng và mật khẩu trong mỗi yêu cầu được kiểm tra đối với cơ sở dữ liệu người dùng và nếu tìm thấy chính xác, chức năng được yêu cầu sẽ thực thi và dữ liệu được trả về máy khách ở định dạng JSON. Nếu tên người dùng và mật khẩu không khớp, một lỗi sẽ được gửi đến máy khách dưới dạng mã lỗi 401 HTTP.
- Thay vì buộc khách hàng gửi tên người dùng và mật khẩu với mỗi yêu cầu, bạn có thể có chức năng "get_access_token" trong dịch vụ RESTful của mình lấy tên người dùng và mật khẩu và trả lời bằng mã thông báo, đó là một loại băm mật mã duy nhất và đã hết hạn ngày gắn liền với nó. Các mã thông báo này được lưu trữ trong cơ sở dữ liệu với mỗi người dùng. Sau đó, khách hàng gửi mã thông báo truy cập trong các yêu cầu tiếp theo. Mã thông báo truy cập sau đó sẽ được xác thực dựa trên cơ sở dữ liệu thay vì tên người dùng và mật khẩu.
- Các ứng dụng khách không có trình duyệt như ứng dụng điện thoại làm tương tự như trên, họ yêu cầu người dùng nhập thông tin đăng nhập của họ, sau đó gửi cho họ (hoặc mã thông báo truy cập được tạo từ họ) với mọi yêu cầu tới dịch vụ web.
Điểm quan trọng lấy đi từ ví dụ này là các dịch vụ web RESTful yêu cầu xác thực với mọi yêu cầu .
Một lớp bảo mật bổ sung trong kịch bản này sẽ thêm ủy quyền ứng dụng khách bên cạnh xác thực người dùng. Ví dụ: nếu bạn có ứng dụng web, ứng dụng iOS và Android đều sử dụng dịch vụ web, bạn có thể muốn máy chủ biết ai trong số ba ứng dụng khách của một yêu cầu cụ thể, bất kể người dùng được xác thực là ai. Điều này có thể cho phép dịch vụ web của bạn hạn chế các chức năng nhất định đối với các khách hàng cụ thể. Đối với điều này, bạn có thể sử dụng các khóa và bí mật API, xem câu trả lời này để biết một số ý tưởng về điều đó.
Xác thực Facebook
Quy trình làm việc ở trên không hoạt động để kết nối Facebook vì đăng nhập qua Facebook có bên thứ ba, chính Facebook. Quy trình đăng nhập yêu cầu người dùng được chuyển hướng đến trang web của Facebook nơi thông tin đăng nhập được đưa ra ngoài tầm kiểm soát của chúng tôi.
Vậy hãy xem mọi thứ thay đổi như thế nào :.
- Người dùng kết nối với
https://example.com
- Máy chủ phục vụ một ứng dụng Javascript phong phú hiển thị trang ban đầu. Ở đâu đó trong trang có một hình thức đăng nhập bao gồm nút "Đăng nhập bằng Facebook".
- Người dùng nhấp vào nút "Đăng nhập bằng Facebook", đây chỉ là một liên kết chuyển hướng đến (ví dụ)
https://example.com/auth/facebook
.
- Các
https://example.com/auth/facebook
tuyến đường được xử lý bởi passport.js (xem tài liệu )
- Tất cả những gì người dùng thấy là trang thay đổi và hiện tại họ đang ở trong một trang được lưu trữ trên Facebook nơi họ cần đăng nhập và ủy quyền cho ứng dụng web của chúng tôi. Điều này là hoàn toàn ngoài tầm kiểm soát của chúng tôi.
- Người dùng đăng nhập vào Facebook và cấp quyền cho ứng dụng của chúng tôi, do đó, Facebook hiện chuyển hướng trở lại URL gọi lại mà chúng tôi đã định cấu hình trong cài đặt Passport.js, theo ví dụ trong tài liệu này là
https://example.com/auth/facebook/callback
- Trình xử lý Passport.js cho
https://example.com/auth/facebook/callback
tuyến sẽ gọi chức năng gọi lại nhận mã thông báo truy cập Facebook và một số thông tin người dùng từ Facebook, bao gồm cả địa chỉ email của người dùng.
- Với email, chúng tôi có thể định vị người dùng trong cơ sở dữ liệu của mình và lưu trữ mã thông báo truy cập Facebook với nó.
- Điều cuối cùng bạn làm trong cuộc gọi lại Facebook là chuyển hướng trở lại ứng dụng khách phong phú, nhưng lần này chúng ta cần chuyển tên người dùng và mã thông báo truy cập cho khách hàng để có thể sử dụng chúng. Điều này có thể được thực hiện theo một số cách. Ví dụ: các biến Javascript có thể được thêm vào trang thông qua công cụ mẫu phía máy chủ hoặc nếu không thì có thể trả lại cookie với thông tin này. (cảm ơn @RyanKimber đã chỉ ra các vấn đề bảo mật khi truyền dữ liệu này trong URL, như tôi đã đề xuất ban đầu).
- Vì vậy, bây giờ chúng tôi bắt đầu ứng dụng một trang một lần nữa, nhưng khách hàng có tên người dùng và mã thông báo truy cập.
- Ứng dụng khách có thể kích hoạt sự kiện "đăng nhập" ngay lập tức và để các phần khác nhau của ứng dụng yêu cầu thông tin mà họ cần từ dịch vụ web.
- Tất cả các yêu cầu được gửi
https://example.com/api
sẽ bao gồm mã thông báo truy cập Facebook để xác thực hoặc mã thông báo truy cập của ứng dụng được tạo từ mã thông báo của Facebook thông qua chức năng "get_access_token" trong API REST.
- Các ứng dụng không phải trình duyệt gặp khó khăn hơn một chút ở đây, vì OAuth yêu cầu trình duyệt web để đăng nhập. Để đăng nhập từ ứng dụng trên điện thoại hoặc máy tính để bàn, bạn sẽ cần khởi động trình duyệt để chuyển hướng sang Facebook, và thậm chí tệ hơn, bạn cần một cách để trình duyệt chuyển mã thông báo truy cập Facebook trở lại ứng dụng thông qua một số cơ chế.
Tôi hy vọng điều này trả lời hầu hết các câu hỏi. Tất nhiên, bạn có thể thay thế Facebook bằng Twitter, Google hoặc bất kỳ dịch vụ xác thực dựa trên OAuth nào khác.
Tôi muốn biết liệu ai đó có cách đơn giản hơn để giải quyết vấn đề này.
passport-facebook
. Sau khi bạn làm việc đó, bước tiếp theo là bắt đầu hiểu cách thức hoạt động của Hộ chiếu và cách lưu trữ thông tin đăng nhập. Kết nối nó để Restify ( xem ở đây để biết phiên bản cập nhật của phiên bản bạn đề cập) sẽ là một trong những bước cuối cùng (hoặc bạn có thể triển khai giao diện REST trong Express).