一、Cookie
1、产生的原因
HTTP请求无状态,每一次请求都是独立的
2、Cookie的实质
服务端(响应)创建Cookie(键值对或字典),并保存到浏览器
3、创建
rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='', ...) 重要参数:slat 加盐 注意:设置cookie要在响应中
4、获取
request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=,) 重要参数:default是,没有此值时返回的值
max_age 单位秒,Cookie失效
5、删除
rep.delete_cookie("key") key为自定义的cookie key
二、Session
1、产生原因
Cookie不安全,并且数据量有限
2、重点
session依赖cookie,把键值对传递保存在服务端
3、过程
存session
a、服务端,创建一个随机字符串
b、创建一个字典,用于保存数据
c、将随机字符串发送给浏览器作为cookie
取session
a、通过cookie获取随机字符串
b、通过字符串获取大字典
c、通过key获取value
4、创建session(和字典相似)
request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置
5、获取session
request.session['k1'] request.session.get('k1',None)
6、删除
del request.session['k1'] # 删除当前会话的所有Session数据 request.session.delete() # 删除当前的会话数据并删除会话的Cookie,最常用 request.session.flush()
7、其它重要的方法
# 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
request.session.clear_expired()
# 清除过期的Session
# 在setting.py文件中添加
SESSION_SAVE_EVERY_REQUEST = True
# 每次请求都保存Session
Django的配置文件
1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用设置项: 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,默认修改之后才保存(默认)
8、注意:Session是存放的数据库django_session里的,别忘记makegriations 和migrate
三、总结
1、Cookie是Session的依赖
2、Cookie的存在浏览器
3、Session存在服务端(数据库)
session实现的简单的登录
from django.shortcuts import render, redirect from app01 import models # Create your views here. # 登录 def login(request): if request.method == "POST": u = request.POST.get("username") pwd = request.POST.get("pwd") user_obj = models.UserInfo.objects.filter(name=u, pwd=pwd).first() # 用户存在 if user_obj: # next_url存在,说明是从其它页面进入login页面的 # /login/?next=/index/ # 若存在登录后,返回原来的页面,若不存在,跳转到index页面 next_url = request.GET.get("next") request.session["user_id"] = user_obj.pk if next_url: return redirect(next_url) else: return redirect("/index/") return render(request, "login.html") # 主页 def index(request): # 若果用户已登录,进入index,否侧返回login,并在login后面添加参数 user_id = request.session.get("user_id") if user_id: return render(request, "index.html") else: nex_url = request.path_info return redirect("/login/?next={}".format(nex_url)) # 注销 def logout(request): request.session.delete() return redirect("/login/")
from django.shortcuts import render, redirect from app01 import models # 登录 def login(request): if request.method == "POST": u = request.POST.get("username") pwd = request.POST.get("pwd") user_obj = models.UserInfo.objects.filter(name=u, pwd=pwd).first() # 用户存在 if user_obj: # next_url存在,说明是从其它页面进入login页面的 # /login/?next=/index/ # 若存在登录后,返回原来的页面,若不存在,跳转到index页面 next_url = request.GET.get("next") request.session["user_id"] = user_obj.pk if next_url: return redirect(next_url) else: return redirect("/index/") return render(request, "login.html") # 主页 # @check_login def index(request): return render(request, "index.html") # 注销 # @check_login def logout(request): request.session.delete() return redirect("/login/")
import re from django.shortcuts import redirect from django.utils.deprecation import MiddlewareMixin class LoginMiddleware(MiddlewareMixin): def process_request(self, request): current_url = request.path_info # 设置白名单 valid_list = ['/login/', '/logout/', '/admin/.*'] for url in valid_list: ret = re.search(url, current_url) if ret: return None user_id = request.session.get("user_id") if user_id: return None else: return redirect("/login/?next={}".format(current_url))
from django.shortcuts import render, redirect from app01 import models from functools import wraps # Create your views here. # 装饰器 def check_login(f): @wraps(f) def inner(request, *args, **kwargs): user_id = request.session.get("user_id") if user_id: return f(request, *args, **kwargs) else: nex_url = request.path_info return redirect("/login/?next={}".format(nex_url)) return inner # 登录 def login(request): if request.method == "POST": u = request.POST.get("username") pwd = request.POST.get("pwd") user_obj = models.UserInfo.objects.filter(name=u, pwd=pwd).first() # 用户存在 if user_obj: # next_url存在,说明是从其它页面进入login页面的 # /login/?next=/index/ # 若存在登录后,返回原来的页面,若不存在,跳转到index页面 next_url = request.GET.get("next") request.session["user_id"] = user_obj.pk if next_url: return redirect(next_url) else: return redirect("/index/") return render(request, "login.html") # 主页 @check_login def index(request): return render(request, "index.html") # 注销 @check_login def logout(request): request.session.delete() return redirect("/login/")