django中的身份验证与扩展的一对一关系

时间:2015-03-05 02:40:31

标签: django django-forms django-views django-authentication django-login

我已经建立了用户可以根据用户模型登录的身份验证系统。在用户模型中,它以一对一的关系扩展。当我使用用户名和密码插入登录时,它的工作原理。但是当我使用用户名,密码和hak_akses插入登录时。它无法正常工作。我希望身份验证可以使用插入用户名,密码和hak_akses。但是,我仍然不知道该怎么做

这是我的urls.py

urlpatterns = patterns('',
    url(r'^login/', views.login, name='login'),
    url(r'^auth/$', views.auth_view, name="auth"),

这是我的模特

class UserProfile(models.Model):
    # This line is required. Links UserProfile to a User model instance.
    user = models.OneToOneField(User)

    # The additional attributes we wish to include.
    CATEGORY_CHOICES = (
        ('admin','Admin'),
        ('user','User'),
        )
    hak_akses = models.CharField(max_length=100, choices = CATEGORY_CHOICES)

    # Override the __unicode__() method to return out something meaningful!
    def __unicode__(self):
        return self.user.username

这是我的观点

def login(request):
    c = {}
    c.update(csrf(request))
    return render_to_response('login.html', c)

def auth_view(request):
    username = request.POST.get('username', '')
    password = request.POST.get('password', '')
    akses = User.objects.select_related().all()
    hak_akses = request.POST.get('hak_akses', '')
    user = auth.authenticate(username=username, password=password, hak_akses=hak_akses)

    if user is not None:
        auth.login(request, user)
        return HttpResponseRedirect('/simofa/')
    else:
        return HttpResponseRedirect('/simofa/login')

这是我的登录模板:

<form class="form-login" method="post" action="/simofa/auth/" name="login">{% csrf_token %}
                <h2 class="form-login-heading">SISTEM MANAJEMEN OTENTIKASI FASILKOM UI</h2>
                <div class="login-wrap">
                    <input name="username" id="username" type="text" class="form-control" placeholder="User ID" autofocus>
                    <br>
                    <input name="password" id="password" type="password" class="form-control" placeholder="Password">
                <br>
                <select name="hak_akses">
                  <option name="hak_akses" value="admin">Admin</option>
                  <option name="hak_akses" value="user">User</option>
                </select>
                    <br>
                    <br>
                    <input type="submit" value="Login" class="btn btn-theme btn-block"><i class="fa fa-lock"></i>
                </div>      
              </form>       

2 个答案:

答案 0 :(得分:0)

如果您正在使用django的身份验证功能(即from django.contrib.auth import authenticate),那么您应该检查身份验证功能的实现方式。请查看django&#39; source code。第72行:

 ....

    try:
        user = backend.authenticate(**credentials)
    except PermissionDenied:

  ....

和backend.authenticate实现如下:

def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)
            if user.check_password(password):
                return user
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a non-existing user (#20760).
            UserModel().set_password(password) 

正如您所看到的,它需要2个参数,用户名和密码,或者如果username是none,那么它需要来自kwargs的用户名。因此,如果您想使用自己的字段hak_akses进行身份验证,则需要编写自己的身份验证后端,如django test custom authentication backend

更简单的解决方案,创建一个将hak_akses作为kwargs并进行身份验证的函数。例如:

def custom_authenticate(self, username=None, password=None, hak_akses=None ):
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
           user_profile = UserProfile.objects.get(user=user)
           if user_profile.hak_akses == hak_akses
              return user_profile
    return None

答案 1 :(得分:0)

我已经解决了我的问题。检查身份验证后的用户名和密码。我必须创建条件来检查hak_akses变量。

def auth_view(request):
    username = request.POST.get('username', '')
    password = request.POST.get('password', '')
    # hak_akses = request.POST.get('hak_akses', '')
    user = auth.authenticate(username=username, password=password)

    if user is not None:
        user_profile = UserProfile.objects.get(user=user)
        auth.login(request, user)
        if user_profile.hak_akses == hak_akses:
            return HttpResponseRedirect('/simofa/')
        else:
            return HttpResponseRedirect('/simofa/login')
    else:
        return HttpResponseRedirect('/simofa/login')

非常感谢@ruddra