2015-08-17 25 views
10

Tôi đang tham khảo một bài đăng SO khác thảo luận về việc sử dụng mã thông báo làm mới với JWT.Thẻ làm mới có thực sự cần thiết khi sử dụng xác thực mã thông báo JWT không?

JWT (JSON Web Token) automatic prolongation of expiration

Tôi có một ứng dụng với một kiến ​​trúc rất phổ biến nơi khách hàng của tôi (web và di động) nói chuyện với một API REST mà sau đó nói chuyện với một lớp dịch vụ và lớp dữ liệu.

enter image description here

Tôi hiểu JWT xác thực thẻ, nhưng tôi là một chút nhầm lẫn như thế nào tôi nên sử dụng thẻ làm mới.

Tôi muốn xác thực JWT của tôi để có các thuộc tính sau:

  1. JWT Mã có hết 2 giờ.

  2. Mã thông báo được làm mới mỗi một giờ theo ứng dụng của khách hàng.

  3. Nếu mã thông báo người dùng không được làm mới (người dùng không hoạt động và ứng dụng không mở) và hết hạn, họ sẽ cần phải đăng nhập bất cứ khi nào họ muốn tiếp tục.

Tôi thấy rất nhiều người cho rằng đây là trải nghiệm tốt hơn khi sử dụng khái niệm mã thông báo làm mới, tuy nhiên tôi không thấy lợi ích của việc này. Nó có vẻ như một sự phức tạp thêm phải quản lý nó.

Câu hỏi của tôi như sau:

  1. Nếu tôi được sử dụng một thẻ làm mới, nó sẽ không còn có lợi để có một thời hạn lâu dài cho thực hành tốt trên token không?
  2. Nếu tôi muốn sử dụng mã thông báo làm mới, mã thông báo đó có được tiếp tục với mã thông báo userId và/hoặc JWT không?
  3. Khi tôi cập nhật mã thông báo mỗi 1 giờ, cách thức hoạt động của mã thông báo này? Tôi có muốn tạo điểm cuối lấy mã thông báo JWT hoặc mã thông báo làm mới của mình không? Điều này có cập nhật ngày hết hạn của mã thông báo JWT gốc của tôi hay tạo mã thông báo mới không?
  4. Có thực sự cần phải có mã thông báo làm mới cho các chi tiết này không? Dường như nếu người dùng chỉ sử dụng mã thông báo JWT để lấy mã thông báo mới (theo liên kết ở trên) thì mã thông báo làm mới đã lỗi thời.

Trả lời

8

Hãy để tôi đặt câu hỏi của bạn một chút sau đó xuống dòng và bắt đầu bằng cách thảo luận về toàn bộ mục đích của mã thông báo làm mới.

Vì vậy, tình huống là:

Người dùng mở ứng dụng và cung cấp bằng chứng xác thực đăng nhập của mình. Bây giờ hầu hết các ứng dụng có thể tương tác với một dịch vụ phụ trợ REST. REST là không trạng thái, không thực sự là một cách để cho phép truy cập vào các API. Do đó, cho đến nay trong cuộc thảo luận, không có cách nào để kiểm tra xem người dùng được ủy quyền có thực sự truy cập vào API hay chỉ là một số yêu cầu ngẫu nhiên sắp tới.

Bây giờ để có thể giải quyết vấn đề này, chúng tôi cần một cách để biết rằng các yêu cầu đến từ một người dùng được ủy quyền. Vì vậy, những gì chúng tôi đã làm là giới thiệu một thứ gọi là mã thông báo truy cập. Vì vậy, bây giờ khi người dùng được xác thực thành công, anh ta được cấp một mã thông báo truy cập.Mã thông báo này được cho là một mã thông báo dài và rất ngẫu nhiên (để đảm bảo rằng nó không thể đoán được). Đây là nơi JWT đi vào hình ảnh. Bây giờ bạn có thể/không muốn lưu trữ bất kỳ chi tiết cụ thể nào của người dùng trong mã thông báo JWT. Lý tưởng nhất là bạn chỉ muốn lưu trữ các chi tiết rất đơn giản, cực kỳ không nhạy cảm trong JWT. Thao tác của hàm băm JWT để lấy các chi tiết của người dùng khác (IDOR, vv) được JWT tự quản lý (thư viện đang được sử dụng).

Vì vậy, hiện tại, vấn đề về quyền truy cập được ủy quyền của chúng tôi đã được giải quyết.

Bây giờ chúng ta nói về một kịch bản tấn công. Giả sử sử dụng tất cả người dùng ở trên Alice, sử dụng ứng dụng, có mã thông báo truy cập được ủy quyền và giờ ứng dụng của cô ấy có thể đưa ra yêu cầu cho tất cả các API và truy xuất dữ liệu theo ủy quyền của cô ấy.

Giả sử rằng SOMEHOW Alice mất Mã thông báo truy cập hoặc đặt một cách khác, đối thủ, Bob, được truy cập vào mã thông báo truy cập của Alice. Bây giờ Bob, mặc dù không được phép, có thể thực sự yêu cầu tất cả các API mà Alice được ủy quyền.

SOMETHING WE IDEALLY KHÔNG MUỐN.

Bây giờ là giải pháp cho vấn đề này là:

  1. Hoặc phát hiện rằng có một cái gì đó thuộc loại này xảy ra.
  2. Giảm cửa sổ tấn công.

Chỉ sử dụng mã thông báo truy cập, rất khó để đạt được điều kiện 1, vì nó là Alice hoặc Bob, mã thông báo được ủy quyền được sử dụng và do đó yêu cầu tạo thành hai người dùng không phân biệt được.

Vì vậy, chúng tôi cố gắng đạt được 2 ở trên và do đó chúng tôi thêm hết hạn hiệu lực của mã thông báo truy cập, giả sử mã thông báo truy cập hợp lệ cho thời gian 't' (ngắn ngủi).

Làm cách nào để trợ giúp? Vâng, ngay cả khi Bob có mã thông báo truy cập, anh ta chỉ có thể sử dụng nó cho đến khi nó hợp lệ. Ngay sau khi nó hết hạn, anh ta sẽ phải lấy lại nó. Bây giờ ofcourse, bạn có thể nói rằng ông có thể làm cho nó giống như cách ông đã nhận nó lần đầu tiên. Nhưng sau đó một lần nữa không có gì giống như an ninh 100%!

Phương pháp trên vẫn có vấn đề và trong một số trường hợp, một trường hợp không thể chấp nhận được. Khi mã thông báo truy cập hết hạn, nó sẽ yêu cầu người dùng nhập thông tin xác thực đăng nhập và nhận lại mã thông báo truy cập được ủy quyền, ít nhất trong trường hợp ứng dụng dành cho thiết bị di động, là trải nghiệm người dùng tồi (không thể chấp nhận).

Giải pháp: Đây là nơi mã thông báo làm mới xuất hiện. Đây lại là mã thông báo không thể đoán trước ngẫu nhiên cũng được phát hành cho ứng dụng cùng với mã thông báo truy cập ngay từ đầu. Mã thông báo làm mới này là mã thông báo đặc biệt rất dài, đảm bảo rằng ngay sau khi mã thông báo truy cập hết hạn, nó yêu cầu máy chủ cho mã thông báo truy cập mới, do đó, không cần phải nhập lại thông tin xác thực đăng nhập của mình mã thông báo truy cập được ủy quyền mới, khi mã thông báo hiện tại đã hết hạn.

Bây giờ bạn có thể yêu cầu, Bob cũng có thể có quyền truy cập vào mã thông báo làm mới, tương tự như cách anh ấy xâm phạm mã thông báo truy cập. VÂNG. Anh ấy có thể. Tuy nhiên bây giờ nó trở nên dễ dàng để xác định một tỷ lệ như vậy, đó là không thể trong trường hợp của một mã thông báo truy cập một mình, và có những hành động cần thiết để giảm thiệt hại thực hiện.

Làm cách nào?

Đối với mỗi người dùng được xác thực (trong trường hợp ứng dụng dành cho thiết bị di động nói chung), một mã thông báo làm mới một bản đồ và cặp mã thông báo truy cập được cấp cho ứng dụng.Vì vậy, tại bất kỳ thời điểm nào, đối với một người dùng được xác thực, sẽ chỉ có một mã thông báo truy cập tương ứng với mã thông báo làm mới. Bây giờ giả sử rằng nếu Bob đã xâm phạm mã thông báo làm mới, anh ta sẽ sử dụng nó để tạo ra một mã thông báo truy cập (vì mã thông báo truy cập là thứ duy nhất được phép truy cập tài nguyên thông qua các API). Ngay khi Bob (kẻ tấn công) đưa ra yêu cầu với mã thông báo truy cập mới được tạo ra, bởi vì mã thông báo truy cập của Alice (người dùng chính hãng) vẫn hợp lệ, máy chủ sẽ thấy điều này là bất thường, bởi vì mã thông báo làm mới chỉ có thể có một mã thông báo được ủy quyền mã thông báo truy cập tại một thời điểm. Xác định sự bất thường, máy chủ sẽ hủy mã thông báo làm mới được đề cập và cùng với tất cả các mã thông báo truy cập được liên kết cũng sẽ bị vô hiệu. Do đó ngăn chặn bất kỳ truy cập thêm, chính hãng hoặc độc hại, với bất kỳ sự cho phép nào yêu cầu tài nguyên. Người dùng, Alice, sẽ được yêu cầu một lần nữa xác thực bằng thông tin đăng nhập của cô ấy và tìm nạp một cặp mã thông báo làm mới và truy cập hợp lệ.

Tất nhiên, bạn vẫn có thể cho rằng Bob có thể truy cập cả mã thông báo làm mới và truy cập và lặp lại toàn bộ câu chuyện ở trên, có khả năng dẫn đến DoS trên Alice, khách hàng thực sự chính hãng, nhưng sau đó lại không có gì Bảo mật 100%.

Cũng như thực hành tốt, mã thông báo làm mới cũng sẽ hết hạn, mặc dù mã thông báo dài.

+0

Đây là câu trả lời tuyệt vời đưa ra một số câu hỏi cho tôi. Cách nào có thể Bob lấy cắp mã thông báo truy cập nếu anh ta không có quyền truy cập vào điện thoại của Alice và mã thông báo chỉ được gửi qua HTTPS? Bạn nói rằng "Đối với mỗi người dùng đã được xác thực (trong trường hợp ứng dụng dành cho thiết bị di động nói chung), một mã thông báo làm mới một và một bản đồ và mã thông báo truy cập được cấp cho ứng dụng". Điều này có nghĩa là Alice không thể sử dụng cùng một mã thông báo trên điện thoại di động và máy tính để bàn của mình không? Nếu vậy, nó sẽ thực tế tương đương với Bob sử dụng cùng một mã thông báo trên một máy khác, phải không? – nomad

+1

@nomad nhiều cách mà mã thông báo truy cập có thể bị xâm phạm. 1. Mất thiết bị của một người. 2. Các ứng dụng đã có một số lỗ hổng rò rỉ các mã thông báo cho các ứng dụng khác trên thiết bị 3. Phiên bản hệ điều hành cơ bản chính nó có lỗ, có thể hoặc có thể không phải là zero ngày 4. Người dùng tự đánh hơi giao thông của riêng mình (HTTPS sẽ không thực sự giúp đỡ) để nhận mã thông báo truy cập và trong trường hợp không sử dụng hết hạn mã thông báo ngay cả sau khi nói ví dụ, cô ấy đã bị chặn sử dụng ứng dụng, v.v. Đối với nhiệm vụ thứ 2, hãy đoán cho mọi thiết bị mới, toàn bộ luồng xác thực sẽ là lặp lại để cấp quyền. Mở để thảo luận. – qre0ct

+0

Đây là một lời giải thích khá tốt. Tôi có một câu hỏi mặc dù: không sử dụng một mã thông báo làm mới vẫn yêu cầu khách hàng cung cấp một id/bí mật? Tôi nghĩ rằng tôi đã nhìn thấy các ví dụ mà bí mật được thông qua (giống như cách bạn ban đầu sẽ cho phép chính mình) và các ví dụ khác chỉ yêu cầu mã thông báo làm mới. Nếu một bí mật không được thông qua, làm thế nào máy chủ auth có thể biết cách ký một mã thông báo truy cập mới, hợp lệ? Nếu một bí mật được thông qua mặc dù, sẽ không yêu cầu một số loại xử lý bên máy chủ (kiểm tra cơ sở dữ liệu ví dụ) để xác nhận khách hàng và bí mật? – georaldc

1

Tôi tin rằng đối với kịch bản này, bạn có thể làm việc với mã thông báo truy cập một mình, làm cho dễ dàng hơn cho khách hàng của bạn nhưng vẫn giữ được lợi ích bảo mật của mã thông báo làm mới.

Đây là cách nó sẽ làm việc:

  1. Khi người dùng đăng của bạn với thông tin (username/password) bạn quay trở lại một ngắn ngủi JWT. Bạn cũng tạo ra một kỷ lục db nơi bạn lưu trữ:

    • JWT id
    • dùng id
    • địa chỉ IP
    • user agent
    • một lá cờ valid (mặc định là TRUE)
    • createdAt
    • updatedAt
  2. Khách hàng của bạn gửi JWT theo mọi yêu cầu. Miễn là JWT chưa hết hạn, nó có quyền truy cập vào các tài nguyên. Nếu JWT hết hạn, bạn làm mới nó đằng sau hậu trường và trả về cả tài nguyên và thêm X-JWT tiêu đề với JWT mới.

  3. Khi khách hàng nhận được phản hồi với tiêu đề X-JWT, nó loại bỏ JWT cũ và sử dụng mã mới cho các yêu cầu trong tương lai.

Làm thế nào sảng khoái JWT làm việc trên máy chủ

  1. Hãy tìm các bản ghi tương ứng db bằng cách sử dụng id JWT.
  2. Kiểm tra xem cờ valid vẫn đúng hay không, nếu không sẽ từ chối.
  3. Tùy chọn, bạn có thể so sánh địa chỉ IP yêu cầu và tác nhân người dùng với địa chỉ IP và tác nhân người dùng được lưu trữ và quyết định từ chối nếu có gì đó trông có vẻ như .
  4. Tùy chọn, bạn có thể kiểm tra các trường được tạo ra của bản ghi db hoặc các trường được cập nhật, và quyết định không làm mới nếu quá nhiều thời gian đã trôi qua.
  5. Cập nhật trường updatedAt trong bản ghi db.
  6. Trả lại JWT mới (về cơ bản là bản sao của JWT hết hạn, nhưng với thời gian hết hạn kéo dài).

Thiết kế này cũng sẽ cung cấp cho bạn tùy chọn thu hồi tất cả mã thông báo cho người dùng (ví dụ: , nếu người dùng mất điện thoại hoặc cập nhật mật khẩu của mình).

Lợi ích:

  • Khách hàng của bạn không bao giờ phải kiểm tra thời gian hết hạn hoặc làm mới thẻ yêu cầu, tất cả nó làm là kiểm tra một X-JWT tiêu đề trên câu trả lời.
  • Bạn có thể thêm logic làm mới tùy chỉnh dựa trên địa chỉ IP, tác nhân người dùng, mã thông báo tối đa hoặc kết hợp những thứ đó.
  • Bạn có thể thu hồi một số hoặc tất cả mã thông báo cho người dùng.
+0

Lưu ý phụ: nếu chúng tôi đang thực hiện các yêu cầu CORS, tiêu đề X-JWT tùy chỉnh sẽ không khả dụng. – tuler

+0

@tuler Nếu bạn muốn hiển thị tiêu đề X-JWT tùy chỉnh trên CORS, bạn sẽ cần phải bao gồm tiêu đề 'Access-Control-Expose-Headers'. Một tùy chọn khác là đưa nó vào phần thân phản hồi dưới dạng siêu dữ liệu. – user293004

Các vấn đề liên quan