Xác thực API REST


181

Tôi đang xây dựng một ứng dụng sẽ được lưu trữ trên máy chủ. Tôi muốn xây dựng API cho ứng dụng để tạo điều kiện tương tác với mọi nền tảng (Ứng dụng web, Ứng dụng di động). Điều tôi không hiểu là khi sử dụng API REST, làm thế nào để chúng tôi xác thực người dùng.

Ví dụ: khi người dùng đã đăng nhập và sau đó muốn tạo một chủ đề diễn đàn. Làm thế nào để tôi biết rằng người dùng đã đăng nhập?


4
Bạn có thể nên tìm kiếm "xác thực REST" ở đây. Nó được đề cập trong nhiều câu hỏi khác.
Brian Kelly

10
Tóm lại, hãy để 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ằng HTTP Basic Auth (qua SSL!) Hoặc xác thực một lần để khách hàng có phiên xác thực sẽ hết hạn sau một khoảng thời gian không hoạt động (hoặc tuy nhiên bạn chọn ghi đè xử lý phiên của khung web của bạn). Phiên đã nói sau đó có thể được lưu trữ trong cookie hoặc là một tham số được truyền với mọi yêu cầu (ví dụ: JSESSIONID trong vùng đất Java).
opyate


@opyate từ quan điểm bảo mật, thực sự không nên xử lý phiên bằng cookie trong trường hợp API REST, vì kẻ tấn công có thể gửi yêu cầu mà không cần sự đồng ý của người dùng. Tốt hơn là bao gồm mã băm hoặc mã thông báo phiên trong tiêu đề HTTP (chẳng hạn như Ủy quyền).
s3v3n

1
@ s3v3n Sửa lỗi cho tôi nếu tôi sai, nhưng cả đề xuất của bạn và tôi chỉ là những cách khác nhau để sử dụng kết hợp tiêu đề + lưu trữ cục bộ để thực hiện cùng một điều. Đó là Authorizationtiêu đề + ví dụ: trình duyệt localStorage VS Cookietiêu đề + lưu trữ cookie trình duyệt tiêu chuẩn.
opyate

Câu trả lời:


72

Bạn có thể sử dụng HTTP Basic hoặc Digest xác thực. Bạn có thể xác thực an toàn người dùng bằng SSL trên đầu trang, tuy nhiên, nó làm chậm API một chút.

  • Xác thực cơ bản - sử dụng mã hóa Base64 trên tên người dùng và mật khẩu
  • Xác thực thông báo - băm tên người dùng và mật khẩu trước khi gửi chúng qua mạng.

OAuth là tốt nhất nó có thể nhận được. Những lợi thế mà oAuth mang lại là một mã thông báo có thể thu hồi hoặc có thể hết hạn. Tham khảo sau về cách triển khai: Liên kết làm việc từ các bình luận: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf


4
Vui lòng đọc câu hỏi này và câu trả lời được cung cấp bởi Les Hazelwood (tác giả của Apache Shiro).
justin.hughey

1
Liên kết hữu ích về cách Twitter bảo vệ API REST: Twitter REST API Security
WildDev

Vì đây là câu trả lời được chấp nhận, tôi cảm thấy rất quan trọng khi đề cập rằng bạn cũng có thể sử dụng xác thực Digest. Đọc về sự khác biệt giữa xác thực Cơ bản và Tiêu hóa tại đây: stackoverflow.com/questions/9534602/NH
Rayee Roded

116

Ví dụ: khi người dùng đã đăng nhập. Làm thế nào để nói người dùng muốn tạo chủ đề diễn đàn, làm sao tôi biết rằng người dùng đã đăng nhập?

Hãy suy nghĩ về nó - phải có một cái bắt tay nói với API "Tạo diễn đàn" của bạn rằng yêu cầu hiện tại này là từ một người dùng được xác thực. Vì API REST thường không trạng thái, trạng thái phải được duy trì ở đâu đó . Khách hàng của bạn sử dụng API REST có trách nhiệm duy trì trạng thái đó. Thông thường, nó ở dạng một số mã thông báo được chuyển qua kể từ thời điểm người dùng đăng nhập. Nếu mã thông báo tốt, yêu cầu của bạn là tốt.

Kiểm tra cách Amazon AWS thực hiện xác thực. Đó là một ví dụ hoàn hảo về việc "vượt qua" từ API này sang API khác.

* Tôi nghĩ đến việc thêm một số phản ứng thực tế cho câu trả lời trước đây của tôi. Hãy thử Apache Shiro (hoặc bất kỳ thư viện xác thực / ủy quyền). Tóm lại, hãy thử và tránh mã hóa tùy chỉnh. Khi bạn đã tích hợp thư viện yêu thích của mình (tôi sử dụng Apache Shiro, btw), bạn có thể thực hiện các thao tác sau:

  1. Tạo API đăng nhập / đăng xuất như: /api/v1/loginapi/v1/logout
  2. Trong các API Đăng nhập và Đăng xuất này, hãy thực hiện xác thực với cửa hàng người dùng của bạn
  3. Kết quả là một mã thông báo (thông thường, JSESSIONID) được gửi lại cho khách hàng (web, di động, bất cứ điều gì)
  4. Từ thời điểm này trở đi, tất cả các cuộc gọi tiếp theo được thực hiện bởi khách hàng của bạn sẽ bao gồm mã thông báo này
  5. Giả sử cuộc gọi tiếp theo của bạn được thực hiện với API được gọi /api/v1/findUser
  6. Điều đầu tiên mà mã API này sẽ làm là kiểm tra mã thông báo ("người dùng này có được xác thực không?")
  7. Nếu câu trả lời trở lại là KHÔNG, thì bạn ném Trạng thái HTTP 401 lại cho máy khách. Hãy để họ xử lý nó.
  8. Nếu câu trả lời là CÓ, thì hãy tiến hành trả lại Người dùng được yêu cầu

Đó là tất cả. Hi vọng điêu nay co ich.


Vì vậy, những gì bạn đang mô tả về cơ bản là một cookie phiên, phải không?
LordOfThePigs

có, nhưng phiên được "duy trì" ở 2 nơi khác nhau. Một trong máy chủ API, một cái khác trong Trình duyệt. Phản hồi JSON (hoặc bất cứ điều gì) trở lại bài đăng đăng nhập thành công sẽ truyền thông id phiên trên máy chủ API trở lại trình duyệt. Các phiên này được quản lý độc lập bởi các đại lý tương ứng của họ.
Kingz

11
Tôi tin rằng Kingz đã cố gắng truyền đạt ý tưởng rằng cơ chế duy trì phiên là cố ý mơ hồ. Một cookie phiên chỉ là một thực hiện của cơ chế đó.
justin.hughey

2
@Kingz, Điều gì về bảo mật trong giải pháp này, ví dụ nếu bất kỳ hacker nào đánh hơi được liên kết với session_id và bắt đầu gửi yêu cầu nội dung nào đúng session_id? Chúng ta có thể giải quyết nó bằng cách thêm ssl vào kết nối máy chủ, nhưng còn khách hàng thì sao?
Ahmad Samilo

1
Làm thế nào để ngăn chặn chiếm quyền điều khiển phiên trong trường hợp người đàn ông trung gian?
m0z4rt

38
  1. Sử dụng HTTP Basic Auth để xác thực ứng dụng khách, nhưng chỉ coi tên người dùng / mật khẩu là mã thông báo phiên tạm thời .

    Mã thông báo phiên chỉ là một tiêu đề được đính kèm với mọi yêu cầu HTTP, ví dụ: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    Chuỗi Ym9ic2Vzc2lvbjE6czNjcmV0 ở trên chỉ là chuỗi "bobsession1: s3cret" (là tên người dùng / mật khẩu) được mã hóa trong Base64.

  2. Để có được mã thông báo phiên tạm thời ở trên, hãy cung cấp hàm API (ví dụ http://mycompany.com/apiv1/login:) lấy tên người dùng chính và mật khẩu chính làm đầu vào, tạo tên người dùng / mật khẩu HTTP Basic Auth tạm thời ở phía máy chủ và trả về mã thông báo (ví dụ: Ym9ic2Vzc2lvbjE6czNjcmV0). Tên người dùng / mật khẩu này phải là tạm thời, nó sẽ hết hạn sau 20 phút hoặc lâu hơn.

  3. Để bảo mật hơn, đảm bảo dịch vụ REST của bạn được cung cấp qua HTTPS để thông tin không được truyền tải bản rõ

Nếu bạn đang sử dụng Java, thư viện Spring Security cung cấp hỗ trợ tốt để triển khai phương thức trên


1
Tại sao nó sẽ hết hạn sau 20 phút? Điều gì xảy ra nếu một trang web như facebook đăng nhập cho đến khi người dùng đăng xuất?
Dejell 16/2/2015

1
@dejel Tôi theo giả định "phiên" là tạm thời về bản chất. Thông thường nó sẽ hết hạn nếu người dùng không sử dụng
gerrytan 29/07/2015

Base64 để làm gì? Bạn chỉ có thể trả lại mật khẩu tạm thời. Trong cả hai trường hợp, điều thực sự quan trọng là mật khẩu tạm thời này rất mạnh. Kiểm tra bảo
mật.stackexchange.com/a/19686/72945

7

Tôi nghĩ cách tiếp cận tốt nhất là sử dụng OAuth2. Google nó và bạn sẽ tìm thấy rất nhiều bài viết hữu ích để giúp bạn thiết lập nó.

Nó sẽ giúp phát triển ứng dụng khách cho API của bạn từ ứng dụng web hoặc ứng dụng di động dễ dàng hơn.

Hy vọng nó sẽ giúp bạn.


2
Xin vui lòng đọc câu hỏi này và câu trả lời của Les Hazelwood (tác giả của Apache Shiro).
justin.hughey

0

Tôi đã sử dụng xác thực JWT. Hoạt động tốt trong ứng dụng của tôi.

Có một phương thức xác thực sẽ yêu cầu thông tin đăng nhập của người dùng. Phương pháp này xác thực thông tin đăng nhập và trả về mã thông báo truy cập trong trường hợp thành công.

Mã thông báo này phải được gửi đến mọi phương thức khác trong API Web của tôi trong tiêu đề của yêu cầu.

Nó khá dễ thực hiện và rất dễ kiểm tra.

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.