1.自定義登錄
1)創(chuàng)建user表
user->models.py
class Users(models.Model):
username=models.CharField(max_length=10,unique=True,verbose_name='用戶名')
password=models.CharField(max_length=255,verbose_name='密碼')
create_time=models.DateTimeField(auto_now_add=True,verbose_name='創(chuàng)建時(shí)間')
operate_time=models.DateTimeField(auto_now=True,verbose_name='修改時(shí)間')
class Meta:
db_table='users'
2)用戶注冊代碼
def register(request):
if request.method=='GET':
# 如果請求為get蔽豺,返回注冊頁面
return render(request,'register.html')
if request.method=='POST':
#校驗(yàn)參數(shù)
form=UserForm(request.POST)
# 判斷是否校驗(yàn)成功呆瞻,is_valid()為true校驗(yàn)成功
if form.is_valid():
# 注冊,使用make_password進(jìn)行密碼加密,否則為明文
password=make_password(form.cleaned_data['password1'])
Users.objects.create(username=form.cleaned_data['username'],
password=password)
# 跳轉(zhuǎn)到登錄頁面彤侍,使用namespace:name
return HttpResponseRedirect(reverse('user:login'))
else:
return render(request,'register.html',{'form':form})
2.設(shè)置裝飾器
1)創(chuàng)建user_ticket表
class UserTicket(models.Model):
#
user=models.ForeignKey(Users)
ticket=models.CharField(max_length=30)
create_time=models.DateTimeField(auto_now_add=True,verbose_name='創(chuàng)建時(shí)間')
max_age=models.DateTimeField(auto_now=True,verbose_name='修改時(shí)間')
class Meta:
db_table='user_ticket'
2)登錄:
def login(request):
if request.method=='GET':
return render(request,'login.html')
if request.method=='POST':
# 校驗(yàn)登錄頁面?zhèn)鬟f的參數(shù)
form=LoginForm(request.POST)
# 使用is_valid()判斷是否校驗(yàn)成功
if form.is_valid():
# 登錄的設(shè)置
# 1.通過用戶名和密碼獲取當(dāng)前的user對(duì)象-->類似authenticate
user=Users.objects.filter(username=form.cleaned_data['username']).first()
if user:
# 可以通過username獲取到對(duì)象
# 將user.password和from.form.cleaned_data['password']進(jìn)行校驗(yàn)
if check_password(form.cleaned_data['password'],user.password):
# 校驗(yàn)用戶名和密碼都成功
#1.向cookie中設(shè)置隨機(jī)參數(shù)ticket
res = HttpResponseRedirect(reverse('user:index'))
ticket=get_ticekt()
# set_cookie(key,value,max_age'',expires=''),key鍵谤民,value值败富,max_age存活時(shí)間-s,expires-天
# 設(shè)置cookie中的隨機(jī)值-->類似auth.login
res.set_cookie('ticket',ticket,max_age=100)
# 刪除cookie,delete_cookie(key)
# delete_cookie('ticket')
# 2.在表user_ticket中設(shè)置這個(gè)ticket和user的對(duì)象關(guān)系
# 設(shè)置user_ticket中ticket的隨機(jī)值
UserTicket.objects.create(user=user,ticket=ticket)
return res
else:
# 密碼錯(cuò)誤
return render(request,'login.html',{'password':'密碼錯(cuò)誤'})
else:
# 登錄系統(tǒng)的用戶不存在
return render(request,'login.html',{'username':'用戶不存在'})
pass
else:
return render(request,'login.html',{'form':form})
3)登錄跳轉(zhuǎn)首頁驗(yàn)證(裝飾器)
方法一:
得到隨機(jī)ticket
utils->functions->get_ticekt
def get_ticekt():
s='1234567890qwertyuiopasdfghjklzxcvbnm'
ticket=''
for i in range(25):
ticket+=random.choice(s)
return ticket
user->views
def index(request):
if request.method=='GET':
# 從cookie中拿ticket
ticket=request.COOKIES.get('ticket')
user_ticket=UserTicket.objects.filter(ticket=ticket).first()
if user_ticket:
#獲取當(dāng)前登錄系統(tǒng)的用戶
user=user_ticket.user
return render(request,'index.html',{'user':user})
else:
return HttpResponseRedirect(reverse('user:login'))
方法二:
創(chuàng)建裝飾器:
# func是一個(gè)函數(shù)绸狐,該函數(shù)是在裝飾器下面的函數(shù)
def is_login(func):
def check(request):
ticket=request.COOKIES.get('ticket')
# 如果cookie中存在設(shè)置的ticket則通過user_ticket表進(jìn)行校驗(yàn)
if ticket:
user_ticket=UserTicket.objects.filter(ticket=ticket).first()
if user_ticket:
return func(request)
else:
# ticket參數(shù)錯(cuò)誤卤恳,則跳轉(zhuǎn)到登錄
return HttpResponseRedirect(reverse('user:login'))
else:
# 沒有登錄
return HttpResponseRedirect(reverse('user:login'))
return check
方法三:
djg6->settings->MIDDLEWARE:末尾添加
'utils.UserAuthMiddleWare.UserMiddleware',
utils中創(chuàng)建UserAuthMiddleWare.py
from datetime import datetime
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
from user.models import UserTicket
class UserMiddleware(MiddlewareMixin):
# 重構(gòu)攔截請求的方法
def process_request(self,request):
# 排除不需要登錄驗(yàn)證的地址
not_login_path=['/user/login/','/user/register/']
path=request.path
# 校驗(yàn)不需要登錄驗(yàn)證的地址
for n_path in not_login_path:
# 如果當(dāng)前訪問的地址是登錄或注冊地址累盗,則直接訪問對(duì)應(yīng)的視圖函數(shù)
if path==n_path:
return None
# ticket=request.COOKIES.get('ticket')
ticket=request.COOKIES.get('ticket')
# 如果請求的cookie中沒有ticket,則跳轉(zhuǎn)到登錄
if not ticket:
return HttpResponseRedirect(reverse('user:login'))
# 刪除user_ticket表中,時(shí)間超過了1000s的記錄
user_tickets = UserTicket.objects.all()
user_tickets.update(max_age=datetime.now())
for user in user_tickets:
times = datetime.timestamp(user.create_time) + 1000000 - datetime.timestamp(user.max_age)
if times < 0:
user.delete()
# 如果請求的user_ticket中沒有與cookie中相等的ticket,則跳轉(zhuǎn)到登錄
user_ticket=UserTicket.objects.filter(ticket=ticket).first()
if not user_ticket:
return HttpResponseRedirect(reverse('user:login'))
# 設(shè)置全局的user
request.user=user_ticket.user
# 返回中間件執(zhí)行結(jié)束突琳,可返回None或可不寫
return None
4)刪除ticket
utils->UserAuthMiddleWare.py
# 刪除user_ticket表中若债,時(shí)間超過了1000s的記錄
user_tickets = UserTicket.objects.all()
user_tickets.update(max_age=datetime.now())
for user in user_tickets:
times = datetime.timestamp(user.create_time) +8*60*60+100 - datetime.timestamp(user.max_age)
if times < 0:
user.delete()
5)注銷
方法一:
views
def logout(request):
if request.method=='GET':
# 注銷寫法
ticket=request.COOKIES.get('ticket')
user_ticket=UserTicket.objects.filter(ticket=ticket).first()
if user_ticket:
user_ticket.delete()
return HttpResponseRedirect(reverse('user:login'))
方法二:
utils->functions.py->is_logout:
def is_logout(func):
def check(request):
ticket = request.COOKIES.get('ticket')
if ticket:
user_ticket = UserTicket.objects.filter(ticket=ticket).first()
if user_ticket:
user_ticket.delete()
return func(request)
else:
return HttpResponseRedirect(reverse('user:login'))
else:
return HttpResponseRedirect(reverse('user:login'))
return check