Django2.0-驗證和授權(3)-User登陸,登出,登陸限制
阿新 • • 發佈:2018-12-16
登入、登出和登入限制
登入
在使用authenticate
進行驗證後,如果驗證通過了。那麼會返回一個user
物件,拿到user
物件後,可以使用django.contrib.auth.login
進行登入。
這裡使用的models是繼承自AbstractBaseUser
的模型
# models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin
class UserManager (BaseUserManager):
def _create_user(self, phone, username, password, **kwargs):
# 這是一個受保護函式,只能被類自己中呼叫
# 作為create_user和create_superuser的被呼叫函式
if not phone:
raise ValueError("必須傳遞手機號碼")
if not password:
raise ValueError("必須傳遞密碼")
user = self.model(phone=phone, username=username, **kwargs) # self.model表示當前模型
user.set_password(password) # password只能這樣設定
user.save()
return user
def create_user(self, phone, username, password, **kwargs):
kwargs["is_superuser"] = False # 新增is_superuser鍵值對
return self._create_user(phone=phone, username=username, password=password, **kwargs)
def create_superuser(self, phone, username, password, **kwargs):
kwargs["is_superuser"] = True
return self._create_user(phone=phone, username=username, password=password, **kwargs)
class InheritTwo(AbstractBaseUser, PermissionsMixin):
phone = models.CharField(max_length=11, unique=True)
username = models.CharField(max_length=20)
password = models.CharField(max_length=20)
address = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = 'phone'
REQUIRED_FIELDS = []
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
配置settings.py
中的AUTH_USER_MODEL='appname.InheritTwo'
,且為第一次資料庫遷移
html編寫
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<table>
<tbody>
<tr>
<td>登陸手機號:</td>
<td><input type="text" name="phone"></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>
<label for="">
<input type="checkbox" name="remember" value="1"> 記住我
</label>
</td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登陸"></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
登陸:
from django.shortcuts import render, redirect, reverse
from .forms import LoginForm
from django.contrib.auth import login, logout
def my_login(request):
if request.method == "GET":
return render(request, 'login.html')
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
phone = form.cleaned_data.get("phone")
password = form.cleaned_data.get("password")
remember = form.cleaned_data.get("remember")
user = authenticate(request, username=phone, password=password)
# authenticate驗證
if user and user.is_active: # 如果存在且不為黑名單
# 在session表中登記資訊
login(request, user)
if remember: # 是否有點"記住我"
# 設定為None,則表示使用全域性的預設時間(2周)
request.session.set_expiry(None)
else:
# 瀏覽器結束即結束
request.session.set_expiry(0)
return HttpResponse("登陸成功")
else:
return HttpResponse("手機或密碼錯誤")
else:
return redirect(reverse('login'))
登出
登出,或者說退出登入。通過django.contrib.auth.logout
來實現。他會清理掉這個使用者的session
資料(表也會清除,類似request.session.flush()
)。
from django.contrib.auth import logout
def my_logout(request):
logout(request)
return HttpResponse("登出成功")
登入限制:使用裝飾器
需要某個檢視函式是需要經過登入後才能訪問的。
通過django.contrib.auth.decorators.login_required
裝飾器來實現。
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/') # 如果驗證失敗,則跳轉login_url指定的頁面
# 會傳遞 next= urls.py中檢視函式對應的urls路徑
# 比如當前函式的urls路徑為 two/profile/ 則傳遞 next=/two/prifle/ <-!!!沒有多一個 /
def profile(request):
return HttpResponse("登陸成功才能看見")
在/login/
的檢視函式中,判斷是否有這個next
查詢字串,決定是否再跳轉到profile
檢視函式
def my_login(request):
# ...
if user and user.is_active: # 如果存在且不為黑名單
# request.session['user_id'] = user.id
login(request, user)
if remember:
# 設定為None,則表示使用全域性的預設時間(2周)
request.session.set_expiry(None)
else:
request.session.set_expiry(0)
next_url = request.GET.get('next') # 裝飾器login_request修飾的函式跳轉後會傳遞next查詢字串
if next_url:
return redirect(next_url) # 跳轉回profile檢視函式
else:
return HttpResponse("登陸成功")
else:
return HttpResponse("手機或密碼錯誤")
# ...