Django Cookie和Session

一、cookie和session的介绍

  

  cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

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

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

  问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。

另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架

二、登录应用原理

  前几节的介绍中我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面。直接输入后台的url地址也可以直接访问的。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。

      先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端,这个被存储在浏览端的东西就叫cookie。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以字典形式存储的,字典的唯一key就是刚才发给用户的唯一的cookie值。那么如果在服务器端查看session信息的话,理论上就会看到如下样子的字典

{'123abc':{'login':true,'username:hahaha'}}

  因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。那么为什么说我们只是理论上看到这样子的字典呢?因为处于安全性的考虑,其实对于上面那个大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在服务器端也是一样被加密的。所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西

{'123abc':dasdasdasd1231231da1231231}

三、cookie的简单使用

获取cookie:如果有值就获取,如果没有则返回None

val = request.COOKIES.get('user','')

设置cookie:

expires:过期时间,是一个日期时间型

path:有效路径,设置的cookie只作用于这个路径以及子路径

max_age:过期时间,单位是秒

        response = redirect('/index/')
            # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie
            date = datetime.date(year=2020,month=12,day=31)
            response.set_cookie('user',user_ret.name,expires=date,path='/index/') 

删除cookie:

response.delete_cookie('user','user_ret.name)

基于登录验证的3次请求过程:

一共有三次请求
  注意:form表单的action走的路径还是/login/
     第一次请求:url:http://127.0.0.1:8080/login GET请求
       第二次请求:url:http://127.0.0.1:8080/login POST请求 user pwd
       第三次请求:url:http://127.0.0.1:8080/index GET请求 携带着cookie的了
       所以在index页面中就会取到cookie,因为这是的index里面已经有cookie了

注意:点击提交时,完成了2次请求,一次是form表单的POST请求,一次是验证成功后return response跳转到index的GET请求

登录验证代码:

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01.models import *
import datetime
import  time
# Create your views here.
def login(request):
    if request.method=='POST':
        print('我是post请求')
        user = request.POST.get('user','')
        pwd = request.POST.get('passwd')
        user_ret = Userinfo.objects.filter(name=user,pwd=pwd).first()
        print('用户名:',user)
        print(user_ret)
        if user_ret :
            response = redirect('/index/')
            # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie
            response.set_cookie('is_login',True) #max_age是以秒计算的,不支持ie
            date = datetime.date(year=2020,month=12,day=31)
            response.set_cookie('user',user_ret.name,expires=date,path='/index/') #
            # response.set_cookie()

            return response
        else:
            return HttpResponse('登录失败')
    print("我是get请求")
    return  render(request,'login.html')

def index(request):
    print('请求类型:',request.method)
    is_login =request.COOKIES.get('is_login')
    if is_login:
        # 登录成功后,取出cookies中设置的user
        username = request.COOKIES.get('user')
        '''显示上次登录时间:
        1,取出上次登录时间last_time,如果没有,则为空
        2,设置这次登录时间login_date
        3,设置这次登录的last_time
        
        '''
        last = request.COOKIES.get('last_time','')  #1
        login_date = time.strftime('%Y-%m-%d %X',time.localtime())#2
        response=render(request,'index.html',{'username':username,'logindate':last})
        response.set_cookie('last_time',login_date)#3
        return response
    else:
        return redirect('/login/')

    # return render(request,'index.html')
View Code

login.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Cookies设置</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    用户名 <input type="text" name="user">
    密码 <input type="password" name="passwd">
    <input type="submit">

</form>
</body>
</html>
View Code

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
<h1>Hi,{{ username }}</h1>
<h2>上次登录时间:{{ logindate }}</h2>
</body>
</html>
View Code

cookie存储到客户端

优点:数据存储在客户端。减轻服务端的压力,提高网站的性能

缺点:安全性不高,在客户端很容易被查看或破解用户会话信息

 四、session的简单使用

1、基本操作(需要掌握的)

1、设置session值
    request.session["session_name"]="admin"
2、获取session值
    session_name = request.session("session_name")
3、删除session值
    del request.session["session_name"]  删除一组键值对
    request.session.flush()   删除一条记录
4、检测是否操作session值
    if "session_name"  in request.session:

其他操作

5、get(key, default=None)
 
fav_color = request.session.get('fav_color', 'red')
 
6、pop(key)
 
fav_color = request.session.pop('fav_color')
 
7、keys()
 
8、items()
 
9、setdefault()
 
10、flush() 删除当前的会话数据并删除会话的Cookie。
            这用于确保前面的会话数据不可以再次被用户的浏览器访问
            例如,django.contrib.auth.logout() 函数中就会调用它。
用户session的随机字符串
        request.session.session_key
  
        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()
  
        # 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")
  
        # 删除当前用户的所有Session数据
        request.session.delete("session_key")
  
        request.session.set_expiry(value)
            * 如果value是个整数,session会在些秒数后失效。
            * 如果value是个datatime或timedelta,session就会在这个时间后失效。
            * 如果value是0,用户关闭浏览器session就会失效。
            * 如果value是None,session会依赖全局session失效策略。
View Code

session配置

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,默认修改之后才保存(默认)
使用session技术,首次登录后,会针对客户端(不同的浏览器,就是不同的客户端),生成一个唯一的sessionid
如果后续使用不同的用户,在相同的客户端(浏览器)登录,那么只会更新session_data中的输入,而不是重新生成sessionid

session流程解析:
1,登录成功后,会在服务器上生成session信息,格式为{'key':value}的字典,包括sessionid,session_data,session_expire
2,生成的sessionid会发送到浏览器上的cookies中,下次登录的时候,浏览器会带着这sessionid发送请求,如果sessionid在服务器中有值(说明还未到过期时间),就可以取出session_data
3,同一个浏览器(客户端),登录不同的用户,会直接删除掉上一次用户的session信息.但是sessionid不会发生改变



原文地址:https://www.cnblogs.com/lovepy3/p/10978787.html