【django6】auth模組
之前構造使用者登入系統都是直接呼叫session來判斷使用者是否登陸/登出,用自定義model儲存使用者資訊,其實系統自帶了auth模組用於登陸系統的構建。
User是auth模組自帶的使用者資料模型,包含賬戶/密碼/郵箱等多個欄位,因此無需自定義model儲存使用者資訊。
User詳細屬性設定可參考http://python.usyiyi.cn/translate/django_182/ref/contrib/auth.html#django.contrib.auth.models.User
User屬性如下:
username:字串型別。必填。30個字元以內。
first_name:字串型別。可選。30個字元以內。
last_name:字串型別。可選。30個字元以內。
email:可選。
password:明文密碼的hash或者是某種元資料。該屬性不應該直接賦值明文密碼,而應該通過set_password()方法進行賦值。
is_active:Boolean型別。用來判斷該使用者是否是可用啟用狀態。在刪除一個帳戶的時候,可以選擇將這個屬性置為False,而不是真正刪除。這樣如果應用有外來鍵引用到這個使用者,外來鍵就不會被破壞。
is_superuser:Boolean型別。該屬性用來表示該使用者擁有所有的許可,而無需明確的賦予給他。
date_joined:datetime型別。建立時間。
除了這些屬性,還可以使用UserProfile儲存使用者的額外資訊。簡單實用方法見http://www.cnblogs.com/esperyong/archive/2012/12/20/2826302.html
建立使用者:
from django.contrib.auth.models import User
user = User.objects.create_user(username, email, password)
user.save()
auth模組中User表的儲存並非明文儲存。
修改密碼:
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new password')
u.save()
auth模組提供authenticate(username=username, password=password)函式判斷使用者是否已經註冊,提供login(request, user)函式進行登陸,提供logout(request)登出。
賬戶密碼驗證:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# the password verified for the user
if user.is_active:
print("User is valid, active and authenticated")
else:
print("The password is valid, but the account has been disabled!")
else:
# the authentication system was unable to verify the username and password
print("The username and password were incorrect.")
如果密碼對於給定的使用者名稱有效它將返回一個User物件。如果密碼無效,authenticate()返回None。
結合login進行使用者登入,login()使用Django的會話框架來將使用者的ID儲存在會話中。
from django.contrib.auth import authenticate, login
def myLoginview(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
...
else:
# Return an 'invalid login' error message.
使用者登出。注意,即使使用者沒有登入,logout()也不會丟擲任何錯誤。當你呼叫logout()時,當前請求的會話資料將被完全清除。所有存在的資料都將清除。
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
只允許已登陸使用者訪問,在檢視函式開始加入驗證
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/')
Django在模板中提供了user和perms可以直接使用,如下
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
許可權和使用者組部分,部落格http://www.cnblogs.com/esperyong/archive/2012/12/20/2826690.html和 http://djangobook.py3k.cn/2.0/chapter14/寫的很好。
############################################################################################################
#################################################登陸驗證系統示例#############################################
############################################################################################################
urls.py
from django.conf.urls import url
from django.contrib import admin
from account import views as account_views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/', account_views.home, name='home'),
url(r'^register/', account_views.register, name='register'),
url(r'^login/', account_views.login, name='login'),
url(r'^logout/', account_views.logout, name='logout'),
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from .forms import LoginForm
from .forms import RigsterForm
# Create your views here.
def home(request):
return render(request, 'account/home.html')
def register(request):
if request.method == 'POST':
form = RigsterForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
email = form.cleaned_data['email']
user = User.objects.create_user(username, email, password)
user.save()
return HttpResponseRedirect('/home')
else:
return HttpResponse('輸入格式錯誤')
else:
form = RigsterForm()
return render(request, 'account/register.html',{'form':form})
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user and user.is_active:
auth_login(request, user)
return HttpResponseRedirect('/home')
else:
return HttpResponse('賬號或使用者名稱錯誤')
else:
form = LoginForm()
return render(request, 'account/login.html',{'form':form})
def logout(request):
auth_logout(request)
return HttpResponseRedirect('/home')
home.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
{%if user.is_authenticated%}
<p>歡迎您,{{user.username}}</p>
<p><a href="/logout">退出</a></p>
{%else%}
<p>歡迎您,請登入。</p>
<p><a href="/login">登陸</a></p>
<p><a href="/register">註冊</a></p>
{%endif%}
</body>
</html>
register.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>註冊</title>
</head>
<body>
<div id="login">
<h2>使用者註冊</h2>
<form method='post'>
{% csrf_token %}
<p><label>賬戶: </label>{{form.username}}</p>
<p><label>郵箱: </label>{{form.email}}</p>
<p><label>密碼: </label>{{form.password}}</p>
<input class="but" type="submit" value="登入">
</form>
</div>
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>登陸</title>
</head>
<body>
<div id="login">
<h2>系統登陸</h2>
<form method='post'>
{% csrf_token %}
<p><label>使用者: </label>{{form.username}}</p>
<p><label>密碼: </label>{{form.password}}</p>
<input class="but" type="submit" value="登入">
</form>
</div>
</body>
</html>