2016-09-12 3 views
0

アプリケーションのカスタムユーザーモデルとカスタム認証を実装しようとしています。
私はモデルを作成して移行を行うことができます。カスタムユーザモデルとカスタム認証がdjangoで動作しません。認証フォームが検証テストに合格していません

from django import forms 
from accounts.models import UserModel 

class AuthenticationForm(forms.Form): 
    login = forms.CharField(max_length=128, required=True) 
    password = forms.CharField(max_length=128, required=True) 

from django.shortcuts import render_to_response, redirect, render 
from django.template import RequestContext 
from django.contrib.auth import login, logout , authenticate 
from accounts.forms import AuthenticationForm 
from django.contrib.auth.decorators import login_required 
def accounts_login(request): 
    context = {} 
    if request.method == "POST": 
     form = AuthenticationForm(request.POST) #getting error here 
     print(form) 
     if form.is_valid(): 
     user = authenticate(login = request.POST["login"], password = request.POST["password"]) 
     if user is not None: 
      print(user) 
      login(request,user) 
      next_url = request.POST["next"] 
      return redirect(next_url, args=(), kwargs={}) 
     #more code - not required here. Let me know if needed. 

認証フォーム - 私は、ユーザーを認証しています

login 
User model with this Login already exists. 

ビュー - 私はフォームを作成し、ログインテンプレートを実装する場合でも、私はこのエラーを取得しています

私のカスタムユーザーモデルとユーザーマネージャー -

from django.db import models 
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager 
from django.utils import timezone 
from django.db.models import Max 

class MyUserManager(BaseUserManager): 
    use_in_migrations = True 
    def create_user(self,login, parent_type, last_name, first_name, password): 
     return create_superuser(self,login, parent_type, last_name, first_name, password) 


    def create_superuser(self,login, parent_type, last_name, first_name, password): 
     maxx = self.model.objects.all().aggregate(Max('sys_id')) 
     print(maxx) 
     user = self.model(
          sys_id = maxx["sys_id__max"] + 1, 
          login = login, 
          password = password, 
          parent_type = parent_type, 
          last_name = last_name, 
          first_name = first_name, 
          display_name = last_name + " " + first_name, 
          created_when = timezone.now() 
         ) 
     user.save(using=self._db) 
     # no difference here...actually can set is_admin = True or something like that. 
     return user 

class UserModel(AbstractBaseUser): 
    # custom user class 
    SYSTEM = 0 
    TENANT = 1 
    parent_type_choices = (
          (SYSTEM, 'System'), 
          (TENANT, 'Tenant') 
          ) 
    sys_id = models.BigIntegerField(primary_key=True, blank=True) 
    parent_type = models.PositiveIntegerField(choices=parent_type_choices, null=False, blank=False) 
    parent_sys_id = models.ForeignKey('tenant.TenantModel', on_delete = models.SET_NULL, null=True, blank=True) 
    last_name = models.CharField(null=False, blank=False, max_length=40) 
    first_name = models.CharField(max_length=40, null=False, blank=False) 
    display_name = models.CharField(max_length=80, unique=True, null=False, blank=True) 
    login = models.CharField(max_length=40, unique=True, null=False, blank=False) 
    authentication_method = models.CharField(max_length=80, null=True, blank=True) 
    access_valid_start = models.DateTimeField(null=True, blank=True) 
    access_valid_end = models.DateTimeField(null=True, blank=True) 
    created_when = models.DateTimeField(null=True, blank=True,) 
    created_by = models.BigIntegerField(null=True, blank=True) 
    last_updated_when = models.DateTimeField(null=True, blank=True) 
    last_updated_by = models.BigIntegerField(null=True, blank=True) 
    notes = models.CharField(max_length=2048, null=True, blank=True) 
    is_active = models.BooleanField(default=True) 

    objects = MyUserManager() 

    USERNAME_FIELD = "login" 
    # REQUIRED_FIELDS must contain all required fields on your User model, 
    # but should not contain the USERNAME_FIELD or password as these fields will always be prompted for. 
    REQUIRED_FIELDS = ['parent_type', 'last_name', 'first_name'] 

    class Meta: 
     app_label = "accounts" 
     db_table = "Users" 

    def __str__(self): 
     return self.display_name 

    def get_full_name(self): 
     return self.display_name 

    def get_short_name(self): 
     return self.last_name 

    def check_password(self,password): 
     return True 
     if self.password ==password: 
      return true 

カスタムバックエンドsetting.pyでこれらの2つの変数を追加しました

from django.conf import settings 
from accounts.models import UserModel 

class MyAuthBackend(object): 
    def authenticate(self, login, password): 
     try: 
      user = UserModel.objects.get(login=login) 
      if user.check_password(password): 
       return user 
      else: 
       print("wrong password") 
       return None 
     except User.DoesNotExist: 
      return None 
     except Exception as e: 
      print(repr(e)) 
      return None 

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

コマンドラインからバックエンドを取得

AUTH_USER_MODEL = 'accounts.UserModel' 
AUTHENTICATION_BACKENDS = ('accounts.backends.MyAuthBackend',) 

>>> get_backends() 
[<accounts.backends.MyAuthBackend object at 0x7f2c438afe80>] 

usernameを持つユーザーは、xyzとパスワード 'ABC'がdbに存在します。
1.私は、既存のユーザー名とパスワードでログインしようとしていた場合、それは私が非既存のユーザ名とパスワード(XYZ123を言うことができます)でログインしようとすると、それは私がauthenticate() takes 0 positional arguments but 2 were given

をエラースロー私はUser model with this Login already exists.
2.例外Error私は複数の記事に続いていましたが、主にこれについてはdjangoの公式文書です。問題を解決するために複数の記事を読むが、失敗した。
私が間違っていることを提案してください。

更新1:AuthenticationFormをModelFormから通常のFormクラスに変更しました。エラー1が解決されました。
更新2:私のカスタムバックエンドをDanielが指摘しているように使用していないので、新しいことは何もしていないので役に立たない。したがって、エラー2も解決される。
更新3:スーパーユーザー機能の作成時にユーザーをdbに保存する前にパスワードをハッシュしました。 user.set_password(password)

答えて

1

まず、パスワードを平文で、上書きされたcreate_superuserメソッドに格納しています。あなたはを絶対にしてはならない。。セキュリティ上の問題とはまったく異なり、認証バックエンドは保存されたバージョンと比較する前に提出されたパスワードをハッシュするので、実際には機能しません。

第2に、実際の問題は、あなたのAuthenticationFormがModelFormであることです。そのようにすれば、のメールとパスワードを持つユーザーを作成できるかどうかを確認しようとします。モデルフォームにする理由はありません。電子メールとパスワード用のCharFieldsを持つ単純なフォームを用意するだけです。

プレーンテキストパスワードの問題を修正するまで、実際にログインすることはできません。また、カスタム認証バックエンドは、in the docsと記載されているインターフェイスに準拠していないことによってauthenticateメソッドを破っただけでなく、組み込みのものがしないものは何もしません。それは無意味なので、あなたはそれを削除する必要があります。

+0

大変ありがとうございます。私はそれらを修正し、物事は現在うまくいっています。私はあなたが質問を落としたとは思わない? – User42

関連する問題