Django Cookie和Session

一、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/")
装饰器
原文地址:https://www.cnblogs.com/wt7018/p/11284177.html