2013-11-22 22 views
19

Tôi đang sử dụng Django-allauth cho thông tin đăng nhập/đăng ký có liên quan của mình, vì vậy khi người dùng đăng ký (lần đầu tiên) vào trang web của tôi, tôi chuyển hướng anh ấy đến trang /thanks/ bằng cách định nghĩa dưới đây thiết lập trong settings.py tập tinChuyển hướng người dùng đến một url khác với tín hiệu đăng nhập django-allauth

LOGIN_REDIRECT_URL = '/ nhờ /'

Nhưng khi người dùng cố gắng đăng nhập cho lần tiếp theo (nếu đã đăng ký) tôi nên chuyển hướng anh '/dashboard/' URL

Vì vậy, cố gắng thay đổi điều đó với Django-allauth signals như dưới đây không hoạt động g ở tất cả

@receiver(allauth.account.signals.user_logged_in) 
def registered_user_login(sender, **kwargs): 
    instance = User.objects.get_by_natural_key(kwargs['user']) 
    print instance.last_login==instance.date_joined,"??????????????????????????????" 
    if not instance.last_login==instance.date_joined: 
     return HttpResponseRedirect(reverse('dashboard')) 

Vì vậy, bất cứ ai có thể vui lòng cho tôi biết làm thế nào để chuyển hướng người dùng đến /dashboard/ cho lần đăng nhập bình thường, tôi đang làm điều gì sai trái trong các mã tín hiệu trên?

Sửa

Sau một vài sửa đổi theo câu trả lời dưới đây bởi pennersr, lớp AccountAdapter của tôi trông giống như dưới đây

from allauth.account.adapter import DefaultAccountAdapter 
# from django.contrib.auth.models import User 

class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
    if request.user.last_login == request.user.date_joined: 
     return '/registration/success/' 
    else: 
     return '/dashboard/' 

Nhưng vẫn còn, nó được chuyển hướng người dùng đến /dashboard/, logic của tôi trong việc xác định lần đầu tiên người dùng sai?

Trả lời

19

Nói chung, bạn không nên cố gắng đặt logic như vậy trong trình xử lý tín hiệu. Điều gì xảy ra nếu có nhiều trình xử lý muốn điều hướng theo các hướng khác nhau?

Thay vào đó, làm điều này:

# settings.py: 
ACCOUNT_ADAPTER = 'project.users.allauth.AccountAdapter' 


# project/users/allauth.py: 
class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
     return '/some/url/' 
+0

Cảm ơn pennersr, tôi đã chỉnh sửa anser của mình ở trên, bạn có thể giúp tôi với điều đó không? –

+0

Ngoài ra, chúng tôi có thể cung cấp cho người dùng tùy chọn gửi lại email xác nhận không? nếu không được xác nhận khi anh ấy đã đăng ký? –

+0

Bạn đã thử kiểm tra các giá trị của last_login/date_joined chưa? Gửi lại email xác nhận diễn ra tự động, ngay khi người dùng cố đăng nhập bằng e-mail chưa được xác minh.Lưu ý rằng để ngăn chặn các cuộc tấn công bằng thư, thao tác này chỉ khởi động khi nỗ lực đăng nhập cách nhau 3 phút. – pennersr

6

Hai datetimes last_logindate_joined sẽ luôn luôn khác nhau, mặc dù nó chỉ có thể là một vài mili giây. đoạn này hoạt động:

# settings.py: 
ACCOUNT_ADAPTER = 'yourapp.adapter.AccountAdapter' 

# yourapp/adapter.py: 
from allauth.account.adapter import DefaultAccountAdapter 
from django.conf import settings 
from django.shortcuts import resolve_url 
from datetime import datetime, timedelta 

class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
     threshold = 90 #seconds 

     assert request.user.is_authenticated() 
     if (request.user.last_login - request.user.date_joined).seconds < threshold: 
      url = '/registration/success' 
     else: 
      url = settings.LOGIN_REDIRECT_URL 
     return resolve_url(url) 

Một nhận xét quan trọng để pennersr câu trả lời: TRÁNH sử dụng tập tin có tên allauth.py vì nó sẽ nhầm lẫn giữa Django và dẫn đến lỗi nhập.

+0

Cảm ơn, điều đó hữu ích –

+0

@ user2292376 Tôi nghĩ rằng 'assert' là không cần thiết ở đây, vì đây là một chuyển hướng đăng nhập, vì vậy người dùng được cho là được xác thực tại thời điểm này được gọi. Tuy nhiên, +1 – Caumons

+0

@ DH1TW tôi tin rằng giải pháp này không phải là hoàn toàn bằng chứng đạn ... tôi chỉ nhận ra rằng nếu người dùng cố gắng đăng nhập thất bại (sai mật khẩu) request.user.last_login vẫn được cập nhật vì lý do nào đó, vì vậy yêu cầu. user.last_login! = request.user.date_joined và thậm chí không ngưỡng có thể lưu nó .. các bạn có giải pháp không? – psychok7

0

Bạn chỉ có thể xác định hai tín hiệu kia bằng cách sử dụng tín hiệu user_logged_in làm cơ sở. Một nơi tốt để đặt nó là trên signals.py bên trong một tài khoản , trong trường hợp bạn có một hoặc trong ứng dụng lõi. Chỉ cần nhớ nhập signals.py vào bạn __init__.py.

from django.dispatch import receiver, Signal 

pre_user_first_login = Signal(providing_args=['request', 'user']) 
post_user_first_login = Signal(providing_args=['request', 'user']) 


@receiver(user_logged_in) 
def handle_user_login(sender, user, request, **kwargs): 
    first_login = user.last_login is None 
    if first_login: 
     pre_user_first_login.send(sender, user=user, request=request) 
    print 'user_logged_in' 
    if first_login: 
     post_user_first_login.send(sender, user=user, request=request) 


@receiver(pre_user_first_login) 
def handle_pre_user_first_login(sender, user, request, **kwargs): 
    print 'pre_user_first_login' 
    pass 


@receiver(post_user_first_login) 
def handle_post_user_first_login(sender, user, request, **kwargs): 
    print 'post_user_first_login' 
    pass 
Các vấn đề liên quan