赞
踩
https://www.cnblogs.com/wupeiqi/articles/5246483.html
保存在服务端的数据(本质上是键值对)
应用:依赖Cookie
作用:保持会话(web网站)
好处:敏感信息不会直接给客户端
cookie进行维持会话,一个浏览器只能存储20个cookie,服务端上限为300cookie
cookie一般不会设置中文
# 中文cookie的设置一般有两种方式
# 1、使用decode('iso-8859-1').encode('utf-8')的方式
# 字符串不能直接使用decode因此,注意使用顺序
# 2、使用json,进行序列化,返回的方式为unique编码的字符串
from django.shortcuts import render,redirect,HttpResponse # Create your views here. def index(request): if request.COOKIES.get('is_login')=='True': return render(request,'index.html') else: return HttpResponse('你没成功!') def login(request): if request.method=='GET': return render(request,'login.html') if request.method=='POST': username=request.POST.get('username') pwd=request.POST.get('pwd') if username=='aaa' and pwd=='666': ret=redirect('index') # 设置cookie的键值对 ret.set_cookie('is_login',True) print('访问成功') return ret else: return redirect('login')
使用装饰器进行封装cookie的分发与验证
#编写装饰器 def wapper(f): #装饰器的参数f为引用@下面的相关函数 def inner(request,*args,**kwargs): # 决定执行先后的分界线 ret=f(*args,**kwargs) return ret return inner # 调用装饰器 @wapper def test(): pass ''' 知识点 函数内部定义一个函数,该函数要调用一下原函数的参数 最外层函数的返回值为内层函数 装饰器的调用 @name ************* 装饰器与Python 的闭包相关联,且知识点与js的函数参数可以为函数高度相似 '''
from django.shortcuts import render,redirect,HttpResponse # Create your views here. #编写装饰器 def wapper(f): def inner(request,*args,**kwargs): is_loin=request.COOKIES.get('is_login') if is_loin=='True': ret=f(request,*args,**kwargs) return ret else: return redirect('login') return inner # 调用装饰器 @wapper def index(request): return render(request,'index.html') # 登录函数设置cookie不变 def login(request): if request.method=='GET': return render(request,'login.html') if request.method=='POST': username=request.POST.get('username') pwd=request.POST.get('pwd') if username=='aaa' and pwd=='666': ret=redirect('index') ret.set_cookie('is_login',True) # print('访问成功') return ret else: return redirect('login')
<!--相关的两个html文件--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陆界面</title> </head> <body> <h1>前进,前进,不择手段的前进</h1> <hr> <form method="post" action=""> {% csrf_token %} 用户名:<input type="text" name="username"> <br> 密码:<input type="password" name="password"> <button type="submit">提交</button> </form> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>自然选择,前进四</h1> </body> </html>
ret.set_cookie('name', 'AA',10)
ret.set_cookie('sex', 'male',10)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyjmwOte-1641355361965)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210326221531916.png)]
rep = HttpResponse(...) 或 rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
参数:
key, 键
value='', 值
max_age=None, 超时时间
expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
path='/', Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
domain=None, Cookie生效的域名
secure=False, https传输
httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
例如
def login(request):
if request.method=='GET':
return render(request,'login.html')
if request.method=='POST':
username=request.POST.get('username')
pwd=request.POST.get('pwd')
if username=='aaa' and pwd=='666':
ret=redirect('index')
ret.set_cookie('is_login',True)
ret.set_cookie('name', 'AA')
ret.set_cookie('sex', 'male')
# print('访问成功')
return ret
else:
return redirect('login')
session的相关数据(键值对)默认存储在服务端的数据库中django_session
表中。
一个用户,一个浏览器只保存一条记录
seesion的默认过期时间是两周,可以手动设置
生成的cookie为加密后的字符串,数据存储在django_session
数据表之中
def login(request): """ 用户名和密码登录 """ if request.method == 'GET': form = LoginForm(request) return render(request, 'login.html', {'form': form}) form = LoginForm(request,data=request.POST) if form.is_valid(): # 用户输入正确,登陆成功 username = form.cleaned_data['username'] password = form.cleaned_data['password'] # 账号可能为邮箱或者是手机号 ''' 查询逻辑:username=手机号或者是邮箱,但是验证码均等于验证码 (username=moblie_phone and password=password)or(username=email and password=password) 属于复杂查询条件,因此使用orm的Q查询 ''' user_obj = models.UserInfo.objects.filter(Q(email=username) | Q(moble_phone=username)).filter( password=password).first() if user_obj: '''登录成功为1''' # session使用步骤 # 1.生成随机字符串 # 2.通过cookie发送到客户端 # 3.保存到服务端值 request.session['username'] = user_obj.username # 上句代码可完成上述的所有操作。 request.session.set_expiry(60 * 60 * 24 * 14) # 设置session的时间为两周 return redirect('home') # 登录失败 form.add_error('username', '用户名或密码错误') return render(request, 'login.html', {'form': form})
request.session.set_expiry(60 * 60 * 24 * 14)
from django.shortcuts import render,redirect,HttpResponse # Create your views here. def index(request): # is_login=request.session['is_login'] ''' 1.从cookie里面拿出了session_id:xxx随机字符串拿出来 2、去django-session表里面查询到相对应的数据 3.反解密用户存储的数据,并获取用户的数据 ''' is_login = request.session.get('is_login') if is_login==True: return render(request,'index.html') else: return redirect('home') def login(request): if request.method=='GET': return render(request,'login.html') if request.method=='POST': username=request.POST.get('username') pwd=request.POST.get('password') if username=='aa' and pwd=='300': # 设置seession request.session['is_login']=True request.session['name']='AA' ''' 1、生成ssesion_id:随机字符串 2、在COOKIE里面加上了键值对:session_id:ZDsrf 3.将用户的数据进行加密并保存到DJANGO-SESSION表里面,形式为一条记录 # 数据库中session_key 随机字符串 # seesion_data:用户加密的数据 ''' return redirect('index')#redict里面的字符串为URL的别名,进行反向解析 else: return HttpResponse('请正常登录')
装饰器函数一般要写在被装饰函数的上方,以免语法错误
def session_author(fn):
def inner(request,*args,**kwargs):
status=request.session.get('is_login')
if status:
ret=fn(request)
return ret
else:
# return redirect('login'),#使用reverse进行反向解析
return redirect(reverse('login'))
return inner
与cookie的装饰器相似。
可以进行增删改查。
增加就是登录时的写入,修改可以直接像字典一样进行修改。
删除seesion
def logout(request):
# 清楚Session
request.session.flush()
return redirect('home')
常用作用户注销登录的实现。
获取seesion
中间件中获取判断
class AuthMiddleware(MiddlewareMixin):
def proccess_request(self,request):中
'''如果用户已登录,则request中赋值'''
user_name=request.session.get('user_name',0)
# 在中间件中获取值,不存在,则默认值是0,获取到用户的user_name
userobj=models.UserInfo.objects.filter(user_name=user_name)
# 根据用户的username去数据库中进行查询,查询到结果userobj赋值给request
# 中,如果request中的tracer有值,则认定为已经登录,反之则认为没登录。
request.tracer=userobj
# 如果tracer的值比较多,则可以定义一个类,专门进行保存
#!/usr/bin/env python # -*- coding:utf-8 -*- import datetime from django.shortcuts import redirect from django.utils.deprecation import MiddlewareMixin from django.conf import settings from web import models class Tracer(object): def __init__(self): self.user = None self.price_policy = None self.project = None class AuthMiddleware(MiddlewareMixin): def process_request(self, request): """ 如果用户已登录,则request中赋值 """ request.tracer = Tracer() user_id = request.session.get('user_id', 0) user_object = models.UserInfo.objects.filter(id=user_id).first() request.tracer.user = user_object # 白名单:没有登录都可以访问的URL """ 1. 获取当用户访问的URL 2. 检查URL是否在白名单中,如果再则可以继续向后访问,如果不在则进行判断是否已登录 """ if request.path_info in settings.WHITE_REGEX_URL_LIST: return # 检查用户是否已登录,已登录继续往后走;未登录则返回登录页面。 if not request.tracer.user: return redirect('login') # 登录成功之后,访问后台管理时:获取当前用户所拥有的额度 # 方式一:免费额度在交易记录中存储 # 获取当前用户ID值最大(最近交易记录) _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first() # 判断是否已过期 current_datetime = datetime.datetime.now() if _object.end_datetime and _object.end_datetime < current_datetime: _object = models.Transaction.objects.filter(user=user_object, status=2, price_policy__category=1).first() request.tracer.price_policy = _object.price_policy # 方式二:免费的额度存储配置文件 """ # 获取当前用户ID值最大(最近交易记录) _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first() if not _object: # 没有购买 request.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first() else: # 付费版 current_datetime = datetime.datetime.now() if _object.end_datetime and _object.end_datetime < current_datetime: request.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first() else: request.price_policy = _object.price_policy """ def process_view(self, request, view, args, kwargs): # 判断URL是否是以manage开头,如果是则判断项目ID是否是我创建 or 参与 if not request.path_info.startswith('/manage/'): return project_id = kwargs.get('project_id') # 是否是我创建的 project_object = models.Project.objects.filter(creator=request.tracer.user, id=project_id).first() if project_object: # 是我创建的项目的话,我就让他通过 request.tracer.project = project_object return # 是否是我参与的项目 project_user_object = models.ProjectUser.objects.filter(user=request.tracer.user, project_id=project_id).first() if project_user_object: # 是我参与的项目 request.tracer.project = project_user_object.project return return redirect('project_list')
Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) b. 使用 def index(request): # 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") # "session_key"指的是 request.session.session_key request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https传输cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存 b. 使用 同上
文件Session
缓存+数据库Session
加密cookie Session
以上方式请点击参考文献进行观看。
def warper(f):
def inner(*args,**kwargs):
print('我是执行前的语句')
ret=f()
print('我是执行后的语句')
return ret# 返回原函数的返回结果
return inner
@warper#执行wapper函数把test1当做参数
def tes1():
print('***********')
return '我是原函数的返回结果'
print(tes1())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。