2016-02-28 62 views
2

我爲Django編寫了一個Twitter後端,並且圍繞Twitter API發佈了一個包裝以使「使用Twitter登錄」發生,並且一切工作都正常,TwitterUser的get也創建了用戶最終被創建後,最終通過身份驗證後將其重定向到主頁面,但在那裏沒有登錄Twitter用戶。 當我打印request.user它是AnonymousUser登錄無法與另一個後端

TwitterUser模型

class TwitterUser(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True) 
    twitter_id = models.CharField(max_length=100, primary_key=True) 
    username = models.CharField(max_length=100) 
    oauth_token = models.CharField(max_length=100) 
    oauth_secret = models.CharField(max_length=100) 
    last_login = models.DateTimeField(auto_now=True, null=True) 

後端

class TwitterBackend(object): 
    def authenticate(self, username=None, token=None, secret=None): 
     if token and secret and username: 
      try: 
       user = TwitterUser.objects.get(username=username) 

       # Econde 
       token = token.encode("utf-8") 
       secret = secret.encode("utf-8") 

       user_oauth_token = user.oauth_token.encode("utf-8") 
       user_oauth_secret = user.oauth_secret.encode("utf-8") 
       if (bcrypt.hashpw(token, user_oauth_token) == user_oauth_token and 
        bcrypt.hashpw(secret, user_oauth_secret) == user_oauth_secret): 
        return user 
       else: 
        return None 
      except TwitterUser.DoesNotExist: 
       return None 
     else: 
      return None 

    def get_user(self, username): 
     try: 
      user = TwitterUser.objects.get(username=username) 
      return user 
     except TwitterUser.DoesNotExist: 
      return None 

哪裏登錄發生

def convert_to_access_token(request): 
    token = request.GET["oauth_token"] 
    verifier = request.GET["oauth_verifier"] 

    oauth_token, oauth_secret, user_id, username = twitter.get_access_token(token, verifier) 

    tw_user = authenticate(username=username, 
         token=oauth_token, 
         secret=oauth_secret) 
    if tw_user is not None: 
     login(request, tw_user) 
     print "authenticated!" 
     return redirect("/") 
    else: 
     oauth_token_hashed = bcrypt.hashpw(b"%s" % oauth_token, bcrypt.gensalt()) 
     oauth_secret_hashed = bcrypt.hashpw(b"%s" % oauth_secret, bcrypt.gensalt()) 

     generated_pass = User.objects.make_random_password(length=50) 

     user = User(username=username, password=generated_pass) 
     user.save() 
     tw_user = TwitterUser(
          user=user, 
          twitter_id=user_id, 
          username=username, 
          oauth_token=oauth_token_hashed, 
          oauth_secret=oauth_secret_hashed) 
     tw_user.save() 

     tw_user = authenticate(username=username, 
          token=oauth_token, 
          secret=oauth_secret) 
     login(request, tw_user) 
     print "created+authenticated!" 
     return redirect("/") 

和後端是在設置文件的視圖

AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend", 
          "myapp.backends.TwitterBackend") 
+0

我認爲( 「/」) '',你必須調用'login(tw_user)'並且你可以從'from django.contrib.auth導入登錄'導入登錄名' –

+0

'login'(request/tw_user)''在'return redirect(「/」)之前調用 – eustass

+1

這裏的文檔:[用自定義用戶模型代替](https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#sub自定義用戶模型)在代替自定義用戶對象時提及'AUTH_USER_MODEL ='<> .TwitterPost''setting。可能在'settings.py'中是測試它的最佳位置。 –

回答

0

我相信你的後端必須是類型Modelbackend,然後返回用戶或None,如果失敗。

例如登錄使用散列碼:

class HashAuthBackend(ModelBackend): 
    def authenticate(self, hash=None): 
     try: 
      user = User.objects.get(profile__login_hash=hash) 
      if user.is_active: 
       return user 
     except: 
      return None 

而且,我不包括前`返回重定向settings.py中的缺省auth

AUTHENTICATION_BACKENDS = ('App.backends.EmailAuthBackend', 
         'App.backends.KioskModelBackend', 
         'App.backends.HashAuthBackend') 
+0

我試着從ModelBackend類繼承,但又不會登錄用戶 – eustass