Câu hỏi Làm thế nào để thực hiện đăng nhập trong một dịch vụ web RESTful?


Tôi đang xây dựng một ứng dụng web với một lớp dịch vụ. Lớp dịch vụ sẽ được xây dựng bằng cách sử dụng một thiết kế RESTful. Suy nghĩ là một thời gian trong tương lai, chúng tôi có thể xây dựng các ứng dụng khác (iPhone, Android, v.v.) sử dụng cùng một lớp dịch vụ như ứng dụng web. Câu hỏi của tôi là điều này - làm thế nào để tôi thực hiện đăng nhập? Tôi nghĩ rằng tôi đang gặp khó khăn trong việc chuyển từ một thiết kế dựa trên động từ truyền thống sang thiết kế dựa trên tài nguyên. Nếu tôi đã xây dựng này với SOAP tôi có lẽ sẽ có một phương pháp gọi là Đăng nhập. Trong REST tôi nên có một tài nguyên. Tôi gặp khó khăn khi hiểu cách tôi nên xây dựng URI của mình để đăng nhập. Có nên là một cái gì đó như thế này:

http: // myservice /{username}? p = {password}

EDIT: Ứng dụng web mặt trước sử dụng khung ASP.NET truyền thống để xác thực. Tuy nhiên tại một số điểm trong quá trình xác thực, tôi cần phải xác thực các thông tin đăng nhập được cung cấp. Trong một ứng dụng web truyền thống, tôi sẽ thực hiện tra cứu cơ sở dữ liệu. Nhưng trong kịch bản này tôi gọi một dịch vụ thay vì thực hiện tra cứu cơ sở dữ liệu. Vì vậy, tôi cần một cái gì đó trong dịch vụ sẽ xác nhận các thông tin được cung cấp. Và ngoài việc xác thực các thông tin được cung cấp, tôi cũng cần một số thông tin về người dùng sau khi họ đã xác thực thành công - những thứ như tên đầy đủ, ID của họ, v.v. Tôi hy vọng điều này làm cho câu hỏi rõ ràng hơn.

Hay tôi không nghĩ về điều này đúng không? Tôi cảm thấy như tôi gặp khó khăn trong việc mô tả câu hỏi của mình một cách chính xác.

Corey


76
2018-01-05 19:13


gốc




Các câu trả lời:


Như S.Lott đã chỉ ra, chúng tôi có hai thứ được gấp ở đây: Đăng nhập và xác thực

Xác thực nằm ngoài phạm vi ở đây, vì điều này được thảo luận rộng rãi và có thỏa thuận chung. Tuy nhiên, những gì chúng ta thực sự cần cho một khách hàng xác thực thành công chính nó chống lại một dịch vụ web RESTful? Phải, một số loại mã thông báo, hãy gọi nó là mã thông báo truy cập.

Vì vậy, tất cả tôi cần là một access-token, nhưng làm thế nào để có được RESTfully như vậy?
Server) Tại sao không chỉ đơn giản là tạo nó?
Khách hàng) Bằng cách nào?
Máy chủ) Đối với tôi, mã thông báo truy cập không có gì khác ngoài tài nguyên. Vì vậy, tôi sẽ tạo một cho bạn để đổi lấy tên người dùng và mật khẩu của bạn.

Do đó, máy chủ có thể cung cấp URL tài nguyên "/ accesstokens", để BẬT tên người dùng và mật khẩu, trả lại liên kết tới tài nguyên mới được tạo "/ accesstokens / {accesstoken}". Ngoài ra, bạn trả về một tài liệu có chứa access-token và a href với liên kết của tài nguyên:

<access-token
  id = "{id mã thông báo truy cập xuất hiện tại đây; ví dụ: GUID}"
  href = "/ accesstokens / {id}"
/>

Có lẽ, bạn không thực sự tạo access-token như một subresource và do đó, sẽ không bao gồm href của nó trong phản hồi.
Tuy nhiên, nếu bạn làm như vậy, khách hàng có thể tạo liên kết thay mặt cho nó hay không? Không!
Hãy nhớ rằng, các dịch vụ web thực sự RESTful liên kết các tài nguyên với nhau theo cách mà khách hàng có thể điều hướng chính nó mà không cần tạo ra bất kỳ liên kết tài nguyên nào.

Câu hỏi cuối cùng bạn có thể có là nếu bạn nên đăng tên người dùng và mật khẩu dưới dạng biểu mẫu HTML hoặc dưới dạng tài liệu, ví dụ: XML hoặc JSON - nó phụ thuộc ... :-)


56
2018-01-17 09:55



Không hoàn toàn theo REST, nhưng đơn giản và có thể đo lường tốt hơn so với những người khác. Cộng với chia sẻ với sự hài hước tốt. - Ted Johnson
Patrick, bạn đang đề xuất điều tương tự như câu trả lời này? stackoverflow.com/a/1135995/14731 - Gili
Mã trạng thái chính xác có phải là 403 khi tên người dùng và / hoặc mật khẩu không khớp không? - sevteen
Đúng là một ý tưởng. Tạo tài nguyên 'accesstoken'. - Sorter


Bạn không "đăng nhập". Bạn "xác thực". Thế giới của sự khác biệt.

Bạn có nhiều lựa chọn thay thế xác thực.

Xác thực HTTP cơ bản, thông báo, NTLM và AWS S3

  • Xác thực HTTP cơ bản và thông báo xác thực. Điều này sử dụng HTTP_AUTHORIZATION tiêu đề. Điều này rất hay, rất đơn giản. Nhưng có thể dẫn đến rất nhiều lưu lượng truy cập.

  • Tên người dùng / Xác thực chữ ký. Đôi khi được gọi là xác thực "ID và KEY". Điều này có thể sử dụng một chuỗi truy vấn.

    ?username=this&signature=some-big-hex-digest 

    Đây là những nơi như Amazon sử dụng. Tên người dùng là "id". "Khóa" là thông báo, tương tự với khóa được sử dụng để xác thực HTTP Digest. Cả hai bên phải đồng ý về tiêu hóa để tiếp tục.

  • Một số loại xác thực dựa trên cookie. OpenAM, ví dụ, có thể được cấu hình như một tác nhân để xác thực và cung cấp một cookie mà máy chủ web RESTful của bạn có thể sử dụng. Khách hàng sẽ xác thực đầu tiên, và sau đó cung cấp cookie với mỗi yêu cầu RESTful.


23
2018-01-05 19:22



@ S.Lott @Corey Người dùng hoàn toàn có thể tương tác với các hệ thống RESTful. Hầu hết các trang web HTML tĩnh là RESTful "services". - Darrel Miller
@ Darrel Miller: "Ý tưởng của bạn ... là thiếu sót" không cung cấp ngữ cảnh phù hợp hoặc bất kỳ điều gì hữu ích. Đó là loại tiêu cực và không quá hữu ích. - S.Lott
@ Darrel Miller: "yêu cầu REST bị giới hạn ... chỉ đơn giản là vô lý". Bất cứ điều gì. Thay vào đó lặp lại những gì sai, có lẽ bạn có thể giải thích những gì là đúng? Bạn có thể cung cấp một tuyên bố tích cực đơn giản thay vì báo cáo tiêu cực? Bạn có thể giải thích những gì REST là thay vì những gì nó không? Có một số lượng vô hạn của những thứ nó không phải là. - S.Lott
@ S.Lott Bạn yêu cầu cho bối cảnh, tôi đã cho bạn bối cảnh. Câu trả lời ban đầu của bạn cho câu hỏi là tốt. Bạn rõ ràng hiểu rõ HTTP. Tôi chỉ cảm thấy cần phải sửa các xác nhận không hợp lệ đã được thực hiện. Bạn mang một đại diện lớn và do đó giọng nói của bạn có trọng lượng. Tuy nhiên, không ai là một chuyên gia trong mọi chủ đề. Theo tôi được xây dựng và giải thích những gì REST là, bạn được tự do để peruse 489 câu trả lời khác tôi đã cung cấp cho các câu hỏi được gắn thẻ REST. Hoặc nếu bạn có một câu hỏi cụ thể, hãy gắn thẻ nó REST và tôi chắc chắn sẽ có một cú đâm vào nó. - Darrel Miller
@ S.Lott 1) ​​Người dùng tương tác với các hệ thống RESTful mọi lúc. 2) HTML là loại phương tiện hoàn toàn hợp lệ cho hệ thống RESTful để trả về. 3) REST không phải là một tập con của HTTP. REST là một phong cách kiến ​​trúc, HTTP là một protcol. 4) Các hệ thống RESTful không giới hạn ở "dịch vụ web" 5) Các hệ thống RESTful có thể mô phỏng một đăng nhập bằng cách sử dụng một số hình thức mã thông báo ủy quyền, mà không gặp phải các vấn đề liên quan đến phiên. - Darrel Miller


Câu hỏi hay, được đặt ra. Tôi thực sự thích câu trả lời của Patrick. Tôi sử dụng một cái gì đó như

- / người dùng / {tên người dùng} / đăng nhập

Với POST và GET đang được xử lý. Vì vậy, tôi đăng một phiên đăng nhập mới với thông tin đăng nhập và sau đó tôi có thể xem phiên hiện tại dưới dạng tài nguyên thông qua GET.

Tài nguyên là phiên đăng nhập và có thể có mã thông báo truy cập hoặc mã xác thực, hết hạn, v.v.

Thật kỳ lạ, người gọi MVC của tôi phải trình bày một mã thông báo khóa / râu thông qua tiêu đề để chứng minh rằng nó có quyền thử và tạo các phiên đăng nhập mới kể từ trang MVC là một ứng dụng khách của API.

Chỉnh sửa

Tôi nghĩ rằng một số câu trả lời và nhận xét khác ở đây là giải quyết vấn đề với bí mật chia sẻ ngoài băng và chỉ xác thực bằng tiêu đề. Điều đó tốt trong nhiều trường hợp hoặc cho các cuộc gọi dịch vụ tới dịch vụ.

Giải pháp khác là lưu trữ mã thông báo, OAuth hoặc JWT hoặc cách khác, có nghĩa là "đăng nhập" đã diễn ra bởi một quy trình khác, có thể là giao diện người dùng đăng nhập thông thường trong trình duyệt dựa trên biểu mẫu POST.

Câu trả lời của tôi là dành cho dịch vụ nằm phía sau giao diện người dùng đó, giả sử bạn muốn đăng nhập và xác thực người dùng và quản lý người dùng được đặt trong dịch vụ REST chứ không phải trong mã MVC của trang web. Đó là dịch vụ đăng nhập của người dùng.

Nó cũng cho phép các dịch vụ khác "đăng nhập" và nhận mã thông báo hết hạn, thay vì sử dụng khóa chia sẻ trước, cũng như các tập lệnh thử nghiệm trong CLI hoặc Postman.


1
2018-06-05 19:35



Chuyển mã thông báo vào tiêu đề, vâng. Chuyển nó như một phần của URL, không. URL được mã hóa khi chuyển tiếp khi bạn sử dụng HTTPS. Tuy nhiên; URL cũng được lưu trữ trong lịch sử trình duyệt và trong nhật ký máy chủ. Có nhiều lý do chính đáng để tránh truyền dữ liệu nhạy cảm về bảo mật trong các tham số truy vấn URL. - Craig


Kể từ khi một chút đã thay đổi kể từ năm 2011 ...

Nếu bạn đang mở để sử dụng công cụ của bên thứ 3 và hơi lệch từ REST một chút cho giao diện người dùng web, hãy cân nhắc http://shiro.apache.org.

Shiro về cơ bản cung cấp cho bạn một bộ lọc servlet để xác thực cũng như ủy quyền. Bạn có thể sử dụng tất cả các phương thức đăng nhập được liệt kê bởi @ S.Lott, bao gồm xác thực dựa trên biểu mẫu đơn giản.

Lọc các URL còn lại yêu cầu xác thực và Shiro sẽ thực hiện phần còn lại.

Tôi hiện đang sử dụng điều này trong dự án của riêng tôi và nó đã làm việc khá tốt cho tôi cho đến nay.

Đây là điều mà mọi người có thể quan tâm. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme


0
2018-06-12 15:46





Điều đầu tiên cần hiểu về REST là truy cập tài nguyên dựa trên Token của nó.Không giống như các cách truyền thống, quyền truy cập được cấp dựa trên xác thực mã thông báo. Nói một cách đơn giản nếu bạn có đúng token, bạn có thể truy cập resources.Now có rất nhiều công cụ khác để tạo token và thao tác.

Đối với câu hỏi đầu tiên của bạn, bạn có thể thiết kế một API Restfull. Thông tin đăng nhập (Tên người dùng và mật khẩu) sẽ được chuyển đến lớp dịch vụ của bạn. Lớp dịch vụ sau đó xác thực các thông tin đăng nhập này và cấp một mã thông báo.Có thể là tên người dùng / mật khẩu đơn giản hoặc có thể là chứng chỉ SSL. Chứng chỉ SSL sử dụng giao thức OAUTH và an toàn hơn.

Bạn có thể thiết kế URI của bạn như thế này- URI cho yêu cầu mã thông báo-> http: // myservice / some-directory / token? (Bạn có thể chuyển Credentilals trong URI này cho Mã thông báo)

Để sử dụng mã thông báo này để truy cập tài nguyên, bạn có thể thêm [Ủy quyền: Vòng bi (mã thông báo)] này vào tiêu đề http của bạn.

Mã thông báo này có thể được khách hàng sử dụng để truy cập vào thành phần khác nhau của lớp dịch vụ của bạn. Bạn cũng có thể thay đổi khoảng thời gian hết hạn của mã thông báo này để tránh lạm dụng.

Đối với câu hỏi thứ hai của bạn, một điều bạn có thể làm là bạn cấp mã thông báo khác nhau để truy cập các thành phần tài nguyên khác nhau của lớp dịch vụ của bạn. Đối với điều này, bạn có thể chỉ định tham số tài nguyên trong mã thông báo của bạn và quyền lớn dựa trên trường này.

Bạn cũng có thể theo các liên kết này để biết thêm thông tin- http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api


0
2018-02-25 10:06





Tôi đã phải đối mặt với cùng một vấn đề trước đây. Đăng nhập không dịch độc đáo sang thiết kế dựa trên tài nguyên.

Cách tôi thường xử lý nó là bằng cách đăng nhập tài nguyên và chuyển tên người dùng và mật khẩu trên chuỗi tham số, về cơ bản đang thực hiện

Leo lên http: // myservice / login? u ={username} & p = {password}

Phản hồi là một loại phiên hoặc chuỗi xác thực có thể được chuyển đến các API khác để xác thực.

Một cách khác để thực hiện GET trên tài nguyên đăng nhập là thực hiện một POST, người thuần túy REST có lẽ sẽ không thích tôi bây giờ :), và truyền vào các tín dụng trong cơ thể. Câu trả lời sẽ giống nhau.


-4
2018-01-05 19:18



Mật khẩu? Mật khẩu văn bản thuần túy? Như một chuỗi truy vấn? Bạn có thực sự có nghĩa là, hoặc bạn có nghĩa là một tiêu hóa của mật khẩu? - S.Lott
Cảm ơn. Điều đó có ý nghĩa. Dưới đây là một câu hỏi tiếp theo - đối với một ứng dụng lớn, bạn sẽ tạo một dịch vụ RESTful lớn cho mọi thứ hoặc chia nhỏ mọi thứ trong các dịch vụ khác nhau? Tôi đã nghĩ đến việc có một dịch vụ chỉ để xác thực và sau đó là các dịch vụ khác nhau cho các mô-đun khác nhau của ứng dụng của tôi. Có bất kỳ lý do tại sao bạn sẽ hoặc sẽ không làm điều đó một cách này hay cách khác? - Corey Burnett
S. Lott: Nó phụ thuộc vào những gì bạn đang cố gắng làm. Tất nhiên nếu bạn có thể làm một tiêu hóa, sau đó bằng mọi cách. Đôi khi một thông báo là không thể. Nếu tùy chọn duy nhất mở cho bạn là gửi mật khẩu văn bản thuần túy, hãy làm điều đó qua SSL, trong trường hợp này, tốt hơn nên sử dụng POST thay vì GET để ngăn trình duyệt nhớ những gì bạn đã gửi. - Alex
Corey: Tôi không chắc rằng tôi hiểu sự khác biệt giữa một dịch vụ web lớn và nhiều dịch vụ web khác nhau. Bạn thường xác định dịch vụ của mình về mặt tài nguyên, chỉ thêm một vài lần là có ý nghĩa. Tôi nghĩ rằng tôi đang thiếu điểm của bạn mặc dù. - Alex
Alex: giả sử rằng tôi có 4 phần chính khác nhau của ứng dụng web của tôi - Báo cáo, Đơn đặt hàng, Tải xuống và Hóa đơn. Nó sẽ có ý nghĩa để có 4 định nghĩa dịch vụ khác nhau hoặc chỉ có 1 định nghĩa dịch vụ? Có lý do cụ thể nào khiến bạn không muốn chia nhỏ mọi thứ trong nhiều dịch vụ khác nhau không? - Corey Burnett