2012-04-05 22 views
11

Trong khi viết một số khung nhìn để trả lời các yêu cầu ajax, tôi thấy nó hơi lạ khi trình trang trí login_required luôn trả về mã trạng thái 302 cho người dùng chưa được xác thực. Vì những quan điểm này là lượt xem ajax, điều này có vẻ hơi không phù hợp. Tôi không muốn người dùng đăng nhập trong trường hợp như vậy, nhưng tôi muốn Django nói với khách hàng rằng xác thực là cần thiết để truy cập vào một khung nhìn như vậy (một 401 phải là mã trạng thái đúng, tôi nghĩ).login_required decorator trên ajax views để trả về 401 thay vì 302

Để đạt được điều này, tôi bắt đầu viết trang trí của riêng mình login_required_ajax, nhưng bằng cách nào đó điều này vượt ra ngoài các kỹ năng của tôi. Đây là những gì tôi đã đưa ra cho đến nay:

def login_required_ajax(function=None,redirect_field_name=None): 
    """ 
    Just make sure the user is authenticated to access a certain ajax view 

    Otherwise return a HttpResponse 401 - authentication required 
    instead of the 302 redirect of the original Django decorator 
    """ 
    def _decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      if request.user.is_authenticated(): 
       return view_func(request, *args, **kwargs) 
      else: 
       return HttpResponse(status=401) 

     if function is None: 
      return _decorator 
     else: 
      return _decorator(function) 

Khi sử dụng trang trí này trên một cái nhìn, tôi nhận được một ngoại lệ ViewDoesNotExist càng sớm càng tôi cố gắng để truy cập vào bất kỳ trang nào trên trang web.

Lần đầu tiên tôi nghĩ rằng sự cố có thể là sự trả về trực tiếp của một HttpResponse khi người dùng không được xác thực, bởi vì đối tượng phản hồi không phải là một cuộc gọi. Nhưng sau đó trang trí nên làm việc miễn là tôi không cố gắng truy cập vào xem trong câu hỏi, phải không? Và nếu điều này thực sự là mấu chốt, làm thế nào tôi có thể viết một trang trí trả về một HttpResponse với mã trạng thái 401?

+1

Một ý kiến ​​cho rằng không phải là về giám đốc của bạn: Bạn cũng có thể giới thiệu một middleware, mà kiểm tra nếu một yêu cầu là một yêu cầu ajax và trả về một '401 'nếu nó phát hiện rằng khung nhìn trả về một' 302' để đăng nhập ... Vì vậy, bạn có thể tiếp tục sử dụng trang trí của Django và xử lý ajax và yêu cầu bình thường khác nhau ... –

+3

Điều đó thực sự đơn giản hơn bạn: "Tạo một trang trí tùy chỉnh và sử dụng trên quan điểm ajax "? ;) – marue

Trả lời

14

Đó là một nỗ lực khá tốt. Dưới đây là một vài vấn đề tôi phát hiện:

  1. Chức năng _decorator của bạn phải trả lại _wrapped_view.
  2. Thụt lề cho khối if function is None của bạn hơi lệch - chức năng login_required_ajax cần trả lại hàm được trang trí.

Đây là trang trí với những thay đổi được thực:

def login_required_ajax(function=None,redirect_field_name=None): 
    """ 
    Just make sure the user is authenticated to access a certain ajax view 

    Otherwise return a HttpResponse 401 - authentication required 
    instead of the 302 redirect of the original Django decorator 
    """ 
    def _decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      if request.user.is_authenticated(): 
       return view_func(request, *args, **kwargs) 
      else: 
       return HttpResponse(status=401) 
     return _wrapped_view 

    if function is None: 
     return _decorator 
    else: 
     return _decorator(function) 
+0

Hoạt động như một sự quyến rũ. Cảm ơn bạn. – marue

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