Django 中的身份验证扩展一对一关系
authentication in django with extending one-to-one relationship
我已经制作了用户可以基于用户模型登录的身份验证系统。在用户模型中,它以一对一的关系进行扩展。当我使用用户名和密码插入登录名时,它起作用了。但是当我使用用户名、密码和 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>
如果您正在使用 django 的身份验证功能(即 from django.contrib.auth import authenticate
),那么您应该检查身份验证功能是如何实现的。从 django 的 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 个参数,用户名和密码,或者如果用户名是 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
我已经解决了我的问题。在我检查用户名和密码等身份验证后。我必须创造条件来像这样检查 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
我已经制作了用户可以基于用户模型登录的身份验证系统。在用户模型中,它以一对一的关系进行扩展。当我使用用户名和密码插入登录名时,它起作用了。但是当我使用用户名、密码和 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>
如果您正在使用 django 的身份验证功能(即 from django.contrib.auth import authenticate
),那么您应该检查身份验证功能是如何实现的。从 django 的 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 个参数,用户名和密码,或者如果用户名是 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
我已经解决了我的问题。在我检查用户名和密码等身份验证后。我必须创造条件来像这样检查 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