cookie-session

1、cookie说明

1.1、cookie的由来?

  因为http请求是没有状态的,每一次请求都是独立的(对于服务端来说,一切都只是原来的样子)

1.2、cookie有效时间?

  cookie关闭浏览器之后,如果没有设置超时时间,键值对就会失效.

1.3、cookie原理

  cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。

1.4、查看cookie

以chremoe为例,右键检查,或者直接按f12
python_day20_Django-4 (cookie_session)_第1张图片

1.5、django中操作cookie

代码共享路径:链接: 密码:3wv2

1.5.1、方法一

set_cookie(key, value)     设置cookie键值对
COOKIES.get("key")        获取
delete_cookie("key")        删除

from django.shortcuts import render, redirect, HttpResponse

# 设置登陆界面
def login(request):
    if request.POST:
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        if username == "xiong" and passwd == "123":
                    # 先获取要返回页面的对象
            ret = redirect("/index/")
                    # 设置cookie的key,value,最后返回页面 
            ret.set_cookie("login",username)
            return ret
    return render(request, "login.html")

def index(request):
   #  获取cookie的值
    ret = request.COOKIES.get("login")
    if ret == "xiong":
        return render(request, "index.html")
    else:
        return redirect("/login")

def logout(request):
    ret = redirect("/login/")
    ret.delete_cookie("login")
    return ret

1.5.2、方法二 [set|get]_signed_cookie

设置cookie值: salt: 加密盐, max_age 过期时长(单位秒)
set_signed_cookie("key","value",salt="xx", max_age=10)   

获取cookie值   key ,value salt加密值
get_signed_cookie("login",default=0,salt="xiongge1111")

def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        next_url = request.GET.get("page")
        if username == "xiong" and passwd == "123":
            if next_url:   # 如果页面存在就跳到输入的页面,不存在就返回home页面
                ret = redirect(next_url)
            else:
                ret = redirect("/home/")
            ret.set_signed_cookie("login","xiong",salt="xiongge1111", max_age=10)
            return ret
    return render(request, "login.html")

def index(request):
    # 获取 键值以及加盐的字符
    ret = request.get_signed_cookie("login",default=0,salt="xiongge1111")
    if ret == "xiong":
        return render(request, "index.html")
    else:
        return redirect("/login")

1.5.3、方法三 装饰器

使用装饰器进行配置
get_full_path : 获取url中的路径消息
path_info:   url_path路径
from functools import wraps   装饰器修复工具

from django.shortcuts import render, redirect, HttpResponse
from functools import wraps
# Create your views here.

def loggin_check(func):
    @wraps(func)    # 装饰器修复工具
    def wapper(request, *args, **kwargs):
        ret = request.get_signed_cookie("login", default=0, salt="xiongge1111")
        if ret == "xiong":
            return func(request, *args, **kwargs)
        else:
            next_url = request.path_info
            print("next_url: ",next_url)
            return redirect("/login/?page={}".format(next_url))
    return wapper

def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        next_url = request.GET.get("page")
        if username == "xiong" and passwd == "123":
            if next_url:   # 如果页面存在就跳到输入的页面,不存在就返回home页面
                ret = redirect(next_url)
            else:
                ret = redirect("/home/")
            ret.set_signed_cookie("login","xiong",salt="xiongge1111", max_age=10)
            return ret
    return render(request, "login.html")

# 获取不到页面中的登陆消息,就会直接返回到login页面
@loggin_check
def home(request):
    username = request.get_signed_cookie("login",default=0,salt="xiongge1111")
    return render(request, "home.html",{"username":username})

html页面, 返回的是在页面中写的值如图
{% csrf_token %}

帐号

密码

python_day20_Django-4 (cookie_session)_第2张图片

2、session说明

  Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。

2.1、session数据存取

存session:
 1:在服务端生成随机字符串,
 2:生成一个和上面随机字符串对应的大字典,用来保存用户的数据
 3:随机字符串当成cookie返回给浏览器
 4:session必须依赖于cookie

 取session:
 1:从请求携带的cookie里面找到随机字符串
 2:拿到随机字符串去 session中找对应的大字典
 3:从大字典中根据Key取值

2.2、session优缺点

 session优点: 
 1:比cookie能存的数据更多
 2:安全性好,数据都保存在服务端

 session缺点:
 1:session数据量大,会占用一些资源,会话保存时间更长

2.3、django中session相关方法

 获取:  request.session.get("key")
 设置: request.session["key"]=value      # 存不存在都设置
             request.session.setdefault("key",value) #存在不设置
 清空session及浏览器cookie request.session.flush()
 只删除浏览器的cookie  request.session.delete()

 将所有Session失效日期小于当前日期的数据删除 :  request.session.clear_expired()

设置会话Session和Cookie的超时时间:  request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。

图片来源: http://www.cnblogs.com/liwenzhou/p/8343243.html
python_day20_Django-4 (cookie_session)_第3张图片

方法一

 from django.shortcuts import render, redirect
# Create your views here.
def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        if username == "xiong" and passwd == "123":
            request.session["login"] = "xiong"      # 设置session 键值对
            next_url = request.GET.get("path")  # 获取路径
            return redirect(next_url)   # 返回浏览器的路径 
    return render(request, "app02/login.html")

def home(request):
    if request.session.get("login"):
        return render(request, "app02/home.html")
    else:
        return redirect("/app02/login/")

# 清空session及cookie
def logout(request):
    request.session.flush()
    return redirect("/app02/login/")

方法二 装饰器

from django.shortcuts import render, redirect
from functools import wraps

def check_login(func):
    @wraps(func)
    def warrper(request,*args,**kwargs):
        next_url = request.get_full_path()
        if request.session.get("login"):
            return func(request,*args,**kwargs)
        else:
            return redirect("/app02/login/?path={}".format(next_url))
    return warrper

# Create your views here.
def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        if username == "xiong" and passwd == "123":
            request.session["login"] = "xiong"
                        # 如果获取不到那么就返回home
            next_url = request.GET.get("path")
            if next_url:
                return redirect(next_url)
            else:
                return redirect("/app02/home/")
    return render(request, "app02/login.html")

def home(request):
    if request.session.get("login"):
        return render(request, "app02/home.html")
    else:
        return redirect("/app02/login/")

@check_login
def index(request):
    return render(request, "app02/index.html")

def logout(request):
    request.session.flush()
    return redirect("/app02/login/")

2.4、django中的session配置

文档来源: http://www.cnblogs.com/liwenzhou/p/8343243.html

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,默认修改之后才保存(默认)

在django项目settings.py文件中增加一行SESSION_COOKIE_NAME = "web.com" 浏览器中对应的session key名就会改变
python_day20_Django-4 (cookie_session)_第4张图片

settings.py文件中修改 SESSION_SAVE_EVERY_REQUEST = True 设置过期时间为10秒, 当页面在刷新的时候,只要在在10秒内刷新,那么就不会过期

方法三 CBV 类函数

from django.shortcuts import render, redirect
from django import views        # 导入视图函数
from functools import wraps
# 类方法装饰器
from django.utils.decorators import method_decorator

def check_login(func):
    @wraps(func)
    def warrper(request,*args,**kwargs):
        next_url = request.get_full_path()
        if request.session.get("login"):
            return func(request,*args,**kwargs)
        else:
            return redirect("/app02/login/?path={}".format(next_url))
    return warrper

# 加在函数上
class HomeView(views.View):
    @method_decorator(check_login)
    def get(self,requset):
        return render(requset, "app02/home.html")

# 加在类上 必须要传name关键字参数
@method_decorator(check_login,name="get")
# @method_decorator(check_login,name="post")
class HomeView(views.View):
    def get(self,requset):
        return render(requset, "app02/home.html")

FAQ:

no such table: django_session
说明没有创建session表,不管是mysql还是sqlite3 都需要执行
python manage.py makemigrations
python manage.py migrate