2011-07-02 34 views
18

Tôi đang sử dụng hệ thống xác thực mặc định với django, nhưng tôi đã thêm vào thư viện OpenID, nơi tôi có thể xác thực người dùng thông qua OpenID. Những gì tôi muốn làm là đăng nhập chúng vào, nhưng có vẻ như sử dụng hệ thống xác thực django mặc định, tôi cần mật khẩu của họ để xác thực người dùng. Có cách nào để giải quyết vấn đề này mà không thực sự sử dụng mật khẩu của họ không?xác thực django mà không cần mật khẩu

Tôi muốn làm điều gì đó như thế này ...

user = ... # queried the user based on the OpenID response 
user = authenticate(user) # function actually requires a username and password 
login(user) 

tôi sớm chỉ để lại ngoài khơi authenticate chức năng, nhưng nó gắn một lĩnh vực backend, đó là yêu cầu của đăng nhập.

+0

Bản sao có thể có của [Đăng nhập thủ công người dùng không có mật khẩu] (http://stackoverflow.com/questions/2787650/manually-logging-in-a-user-without-password). – easoncxz

Trả lời

2

Bạn có thể dễ dàng khắc phục điều này bằng cách tạo riêng của mình authentication backend và thêm nó vào cài đặt AUTHENTICATION_BACKENDS.

Có một số chương trình phụ trợ OpenID sẵn có, vì vậy với một chút tìm kiếm, bạn có thể tự khắc phục sự cố khi viết một.

+0

Tôi đã gặp sự cố với các chương trình phụ trợ của Django OpenID vì chúng không tương thích với cách làm OpenID độc đáo của Google. Dù sao, như tôi đã nói tôi đã có một backend dựa trên mật khẩu và tôi chỉ muốn sử dụng OpenID trong một số trường hợp - không chuyển sang một phụ trợ OpenID nghiêm ngặt. – voodoogiant

+0

@voodoogiant: tùy thuộc vào các đối số từ khóa phụ trợ xác thực được chọn. Vì vậy, nếu bạn sử dụng 'openid_token' cho chương trình phụ trợ OpenID của bạn và' tên người dùng' bằng 'mật khẩu' cho hệ thống xác thực thông thường của bạn thì cả hai sẽ hoạt động. – Wolph

8

Đây là một chút của một hack nhưng nếu bạn không muốn phải viết lại một loạt các công cụ loại bỏ các xác thực

user.backend = 'django.contrib.auth.backends.ModelBackend' 
login(request, user) 

dùng sẽ là đối tượng người dùng của bạn

+4

Đó là một giải pháp khả thi, nhưng điều đó không được lưu trữ trong phiên, vì vậy nếu bạn mở một tab mới và truy cập trang web, bạn phải đăng nhập lại. – voodoogiant

+1

Điều này S be được lưu trong phiên làm việc và làm việc trong các khung nhìn tiếp theo. Bí quyết duy nhất là chương trình phụ trợ bạn đặt phải được bao gồm trong cài đặt AUTHENTICATION_BACKENDS. Tôi ước gì tôi có thể hoàn tác sự suy sụp của mình, nhưng tôi không thể. –

+0

@voodoogiant, tôi đã gặp chính xác cùng một vấn đề, đó là phiên không được lưu trữ. Nhưng đủ kỳ lạ, 2 yêu cầu XHR đầu tiên có thể nhận dữ liệu phiên từ id phiên. Nhưng sau đó XHR yêu cầu không, và Django máy chủ thiết lập phiên id trong cookie để trống chuỗi trong phản ứng. Bạn có biết tại sao? và làm thế nào để giải quyết điều đó? – jcyrss

19

Nó đơn giản để viết một tùy chỉnh xác thực phụ trợ cho việc này. Nếu bạn tạo yourapp/auth_backend.py với các nội dung sau:

from django.contrib.auth.backends import ModelBackend 
from django.contrib.auth.models import User 


class PasswordlessAuthBackend(ModelBackend): 
    """Log in to Django without providing a password. 

    """ 
    def authenticate(self, username=None): 
     try: 
      return User.objects.get(username=username) 
     except User.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return User.objects.get(pk=user_id) 
     except User.DoesNotExist: 
      return None 

Sau đó thêm vào settings.py của bạn:

AUTHENTICATION_BACKENDS = (
    # ... your other backends 
    'yourapp.auth_backend.PasswordlessAuthBackend', 
) 

Theo quan điểm của bạn, bây giờ bạn có thể gọi xác thực mà không có một mật khẩu:

user = authenticate(username=user.username) 
login(request, user) 
+12

Công cụ này tuyệt vời nhưng hãy cẩn thận - nếu bạn muốn sử dụng auth thông thường trong một số trường hợp, cũng như không có mật khẩu auth ở những người khác, hãy chắc chắn để ngăn chặn phụ trợ mới của bạn gây ra mọi nỗ lực với một tên người dùng hợp lệ để thành công - hãy nhớ rằng tất cả các phụ trợ cố gắng khi authenticate() được gọi. Trong tôi, tôi yêu cầu một đối số mã thông báo đặc biệt để được bao gồm để đảm bảo rằng người gọi xác thực() thực sự muốn không có mật khẩu auth để làm việc. – Richard

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