对于经常网购的朋友来说,经常会遇到一种情况:

打开淘宝或京东商城的首页,输入个人账号和密码进行登陆,然后进行购物,支付等操作都不需要用户再次输入用户名和密码

但是如果用户换一个浏览器或者等几个小时后再刷新这些网页进行购物操作,就必须要再次输入用户名和密码了.

这是为什么呢??这就用到了cookiesession的知识了.

1. cookie的简介

1、http是无状态协议,cookie不属于http协议范围.

在实际应用中,服务端与客户端需要保持连接状态,此时就需要使用到cookie.

cookie的工作原理是:由服务器产生客户端身份信息发送给客户端,客户端收到信息后保存在本地;

当客户端浏览器再次访问服务端时,会自动带上这段身份信息,服务器通过这段信息来判断客户端的身份。

打开chrome浏览器,在地址栏里输入www.cnblogs.com,回车在检查中可以的信息如下图所示:

其中,可以看到此次的请求头(Request Headers):

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:__gads=ID=ec125291e23201fe:T=1504664243:S=ALNI_MZTHHsRs1K2HAD8kB_Q7zN777zCMA
Host:www.cnblogs.com
If-Modified-Since:Sat, 09 Sep 2017 12:38:59 GMT
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36

在这些信息里,可以看到cookie信息是包含在请求头里的.

浏览器发请求的时候,会从浏览器中取出cookie附加到请求头上,给服务端发过去.服务端接收到客户端的cookie之后,会给客户端返回相应的信息.

还可以看到服务端的响应头(Response Headers):

Cache-Control:public, max-age=19
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Sat, 09 Sep 2017 12:42:16 GMT
Expires:Sat, 09 Sep 2017 12:42:36 GMT
Last-Modified:Sat, 09 Sep 2017 12:42:06 GMT
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Frame-Options:SAMEORIGIN
X-UA-Compatible:IE=10

2、cookie在一定程度上解决了"保持状态"的需求

由于cookie本身最大支持4096字节,并且cookie保存在客户端,可能被拦截或窃取,

因此需要有一种新的东西,它来弥补cookie的一些缺陷,并且保存在服务端,有较高的安全性,这就是session。

基于http协议的无状态特征,服务器不知道访问者的身份,此时cookie就起到桥接的作用。

服务端给每个客户端的cookie分配一个唯一的随机id,用户在访问服务端时,服务器通过cookie来判断客户端的身份。

服务端根据cookie的id的不同,在一定的期限内保存客户端传送过来的账号密码等关键信息.

3、cookie弥补了http无状态的不足,让服务器能够判断客户端的身份;

cookie以文本的形式保存在本地,自身安全性较差,因此服务端通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。

4、cookie和session其实是共通性的东西,不限于语言和框架

2.cookie和session的工作机制

每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证,服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端.

这个被存储在浏览器端的东西就叫cookie。而服务器端也会存储一下用户当前的状态,比如login=trueusername="name"之类的用户信息。

这种信息是以字典形式存储成为一个字符串,这串字符串以用户第一次请求时得到的cookie值为键,这就是session.

那么如果在服务器端查看session信息的话,理论上就会看到如下样子的类似的字典

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

因为每个cookie都是唯一随机的,所以我们在同一台电脑上换个浏览器再登陆同一个网站也需要再次验证。

那么为什么说我们只是理论上看到这样子类似的字典呢?因为处于安全性的考虑,其键和值在服务器端都会被加密。

所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西:

{'123abc':dasdasdasd1231231da1231231}

3.cookie和session的初步使用

例子:制作一个登陆页面,服务端使用cookie和session验证了用户名和密码后才能跳转到后台的页面。

3.1 首先创建一个Django的项目,配置好urls和settings,templates中创建一个login.html和index.html页面

views中的代码:

def index(request):
return render(request,"index.html") def login(request):
print("cookie:",request.COOKIES)#打印cookie信息
if request.method=="POST":#如果浏览器使用post方式提交信息
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
return redirect("/index/") return render(request,"login.html")

login页面:

<form action="/login/" method="post">
<p>姓名<input type="text" name="username"></p>
<p>密码<input type="password" name="password"></p>
<p><input type="submit"></p>
</form>

index页面:

<h3>welcome to index page</h3>

打开浏览器,输入http://127.0.0.1:8000/login/打开login页面,输入正确的用户名和密码,进入index页面

此时可以在后端看到如下的cookie信息

cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp'}

其中sessionid中的信息就是Django分配给浏览器的一段随机字符串.

3.2 由用户自己设置cookie信息

修改login视图函数:

def login(request):
print("cookie:",request.COOKIES)
if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
res=redirect("/index/")
res.set_cookie("login_message","hello python")#设置cookie信息
return res
return render(request,"login.html")

然后重启应用,重新输入用户名和密码,进入index页面,此时可以看到如下的cookie信息:

cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp', 'login_message': 'hello python'}

可以看到在后端的login视图函数中设置的cookie的键值对,浏览器请求后又会被服务端接收.

用户请求页面时,是带着标示自己的身份信息的,服务端对客户端的身份信息进行判断,只有身份正确,才能进入index页面.

但是如果在浏览器的地址中直接输入index的路由地址,也能进入index的页面的情况,这不符合我们的要求.

3.3 实现客户端没有cookie,即使用户输入index路由信息,服务端发送登录页面给用户

如果客户端没有cookie,说明用户名或密码没有验证成功,服务端就会把login页面发送给客户端浏览器,

只有用户输入正确的用户名和密码,服务端才会把index页面发送给客户端浏览器.

修改index视图函数:

def index(request):
if request.COOKIES.get("login_message")=="hello python":
return render(request,"index.html",locals())
else:
return redirect("/login/")

这样用户在一个浏览器中经过验证进入index.html页面后,清除cookie或者更换一个浏览器再想进入index页面,就要再次验证用户名和密码了.

由于用户的cookie信息保存在客户端,每与服务端通信一次,客户端就要把cookie信息发送经服务端一次,而且保存在客户端也不够安全,所以又出现了session

session也保存客户端身份的信息,用户登录后服务端把表示用户身份的信息保存成以键值对形式存在的session中,然后服务端把这个字典发送给客户端的cookie,

这时客户端的cookie就以一个字符串的形式存在.

客户端使用cookie和session与服务端进行通信的步骤:

用户经过用户名和密码验证登陆后,生成一个字典,将字典存入session,session的key是自动生成一段字符串标识,也就是前面说过的cookie.
服务端返回给客户端session,session的value存储了用户的关键信息,如user和iflogin等.

在Django中用到session时,cookie由服务端随机生成,写到浏览器的cookie中,每个浏览器都有自己的cookie值,是session寻找用户信息的唯一标识

每个浏览器请求到后台接收的request,这时的session等价于标识用户身份信息的字典

3.4 使用cookie加session来完成上面的例子

修改views中的login视图函数

def login(request):
print("cookie:",request.COOKIES)
print("session:",request.session) if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456": res=redirect("/index/")
res.set_cookie("login_message","hello python")
return res return render(request,"login.html")

再次刷新浏览器,输入正确的用户名和密码后,打印cookie和session:

cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp', 'login_message': 'hello python'} session: <django.contrib.sessions.backends.db.SessionStore object at 0x00000000043D7D30>

可以看到的是此时的session是一个对象.

知道了cookie和session的情况后,那么该怎么使用cookie和session呢

修改视图函数

def index(request):
if request.session.get("is_login",None):#获取session中用户登录的信息
name=request.session.get("user")#获取session中的用户名
return render(request,"index.html",locals())
else:
return redirect("/login/") def login(request):
print("cookie:",request.COOKIES)
print("session:",request.session) if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password") if name=="hello" and pwd=="123456":
request.session["is_login"]=True
request.session["user"]=name
return redirect("/index/")
return render(request,"login.html")

先使用

python manage.py makemigrations
python manage.py migrate

命令初始化数据库,

然后在浏览器中输入http://127.0.0.1:8000/index/后,直接进入登录页面了,输入正确的用户名和密码,后端会打印如下信息:

cookie: {}
session: <django.contrib.sessions.backends.db.SessionStore object at 0x00000000043B46D8>

4 cookie和session的用法:

4.1 操作cookie

获取cookie            request.COOKIE[key]
设置cookie response.set_cookie(key,value)

由于cookie保存在客户端的电脑上,所以jQuery也可以操作cookie

在上面的例子中,在html页面中就使用Django的语法可以渲染name变量.

设置cookie的失效时间:

import datetime#导入datetime模块

response.set_cookie("username",{"11":"22"},max_age=10,
expires=datetime.datetime.utcnow()+datetime.timedelta(days=3))

其中:

datetime.datetime.utcnow()表示当前时间
datetime.timedelta(days=3)表示3天

上面的代码表示设置cookie在当前时间的3天后失效

4.2 操作session(session默认在服务端保存15天)

获取session       request.session[key]或者request.session.get(key)
设置session request.session[key]=value
删除session del request.session[key]

需要注意的是,删除服务端的session不会删除数据库中的session_data,而只是把session更新为一个其他的值

设置session的失效时间:

request.session.set_expiry(value)是设置session的失效时间

参数说明:

如果value是一个整数,session会在整数称后失效
如果value是个datatime或者timedelta,session会在这个时间之后失效
如果value是0,用户关闭浏览器后session就会失效
如果value是None,session会依赖全局session的失效策略

cookie和session的那些事的更多相关文章

  1. cookie 和 session 的一些事 中间件

    cookie 和 session cookie 1. 保存在浏览器上一组组键值对,服务器让浏览器进行设置. 2. 为什么要用cookie? HTTP协议是无状态.使用cookie保存状态. 3. dj ...

  2. cookie、session和token那些事

    cookie 和 session 众所周知,HTTP 是一个无状态协议,所以客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,如何能把一个用户的状态数据关联起来呢? 比如在淘宝的某个 ...

  3. java的会话管理:Cookie和Session

    java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...

  4. Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)

    通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...

  5. 关于Cookie和Session的优缺点

    关于Cookie和Session的优缺点 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. Cookie的优缺点:优点:极高的扩展性和可用 ...

  6. Cookie与Session详解

    来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...

  7. 关于Cookie安全性设置的那些事

    一.标题:关于Cookie安全性设置的那些事 副标:httponly属性和secure属性解析 二.引言 经常有看到XSS跨站脚本攻击窃取cookie案例,修复方案是有httponly.今天写出来倒腾 ...

  8. day07 Cookie 和 Session(非常重要)

    day07 Cookie 和 Session 1. 会话技术 2. cookie 的方法和 cookie 案例-显示用户上次访问网站的时间 3. cookie 的细节 - 删除 cookie 4. S ...

  9. 【10】Cookie和Session

    一.cookie和session的介绍 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要"保持状态",因此cookie就是在这样一个场景下 ...

随机推荐

  1. 洛谷 P1598 垂直柱状图【字符串+模拟】

    P1598 垂直柱状图 题目描述 写一个程序从输入文件中去读取四行大写字母(全都是大写的,每行不超过72个字符),然后用柱状图输出每个字符在输入文件中出现的次数.严格地按照输出样例来安排你的输出格式. ...

  2. Codeforces Round #410 (Div. 2)(A,字符串,水坑,B,暴力枚举,C,思维题,D,区间贪心)

    A. Mike and palindrome time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...

  3. [bzoj2594][Wc2006]水管局长数据加强版 (lct)

    论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...

  4. BZOJ1786: [Ahoi2008]Pair 配对/1831: [AHOI2008]逆序对

    这两道题是一样的. 可以发现,-1变成的数是单调不降. 记录下原有的逆序对个数. 预处理出每个点取每个值所产生的逆序对个数,然后dp转移. #include<cstring> #inclu ...

  5. 2017ecjtu-summer training #1 UVA 12050

    A palindrome is a word, number, or phrase that reads the same forwards as backwards. For example, th ...

  6. GitHub上传文件不能超过100M的解决办法

    http://blog.csdn.net/u010545480/article/details/52995794     上传项目到GitHub上,当某个文件大小超过100M时,就会上传失败,因为默认 ...

  7. 百度分享到qq空间失败

    QQ做了限制的,localhost是不会返回结果的,要用正式域名访问就可以了

  8. APACHE服务器出现No input file specified.的完美解决方案

    转自:http://www.upupw.net/server/n53.html 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:"No input file s ...

  9. Java 中判断类和实例之间的关系

    判断类与实例的关系有以下三种方式 1.instanceof关键字,用来判断对象是否是类的实例 (对象 => 类 )   2.isAssignableFrom,用来判断类型间是否存在派生关系 (类 ...

  10. Netty 拆包粘包和服务启动流程分析

    Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你能掌握EventLoopGroup的工作流程,ServerBootstrap的启动流程,ChannelPipeline是如何操作管理Ch ...