cookie,session,localstorage区别,cookie,session,token
以及Cookie和SessionCookieCookie的由来大家都知道HTTP协议是无状态的。
无状态意味着每个请求都是独立的,它的执行和结果与前面和后面的请求没有直接关系。它不会直接受到前一个请求的响应或后一个请求的响应的影响。
用一个有趣的词来形容,人生就像第一眼。对于服务器来说,每一个请求都是全新的。
状态可以理解为客户端和服务器在某个会话中产生的数据,也就是说不会保留无状态的数据。会话中生成的数据就是我们需要保存的,也就是说“保持状态”。因此,Cookie就是在这样的场景下诞生的。
什么是CookieCookie特指一小段信息。它是由服务器发送并存储在浏览器中的一组键值对。下次访问服务器时,浏览器会自动携带这些键值对,以便服务器提取有用的信息。
Cookie的工作原理是:内容由服务器生成,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带来Cookie,让服务器通过Cookie的内容判断这是谁。
检查Cookie我们使用Chrome浏览器,打开开发者工具。
姜戈的曲奇行动。cookie[ key ]
request.get _ signed _ cookie的参数(key,default=raise _ error,salt= ,max _ age=none):
Default:默认值salt:加密salt max_age:后台控制过期时间设置CookieDjango设置Cookie:(用于响应对象)
rep=HttpResponse(.)
rep=render(请求,)
rep.set_cookie(键,值,)
Rep.set _ signed _ cookie (key,value,salt= encryption salt ,)参数:
Key,key value=“”,value max_age=None,timeout expires=None,timeout (ie要求expires,所以如果还没有设置,就设置它。)path=/,cookie生效的路径,/表示根路径,特殊:根路径中的cookie可以被任何url访问。Domain=none,cookie生效的域名为secure=false,httpS传输为httponly=False,只能通过HTTP协议传输,JavaScript无法获取(非绝对,底层捕获可以获取或覆盖)。删除Cookiedef注销(请求):
rep=redirect(/login/)
Rep.delete_cookie(user) #删除用户浏览器上先前设置的usercookie值
return repSessionSession的起源在一定程度上解决了“保持状态”的需要,但是由于Cookie本身最大支持4096字节,而且Cookie本身存储在客户端,可能会被拦截或者窃取,所以需要有新的东西,可以支持更多的字节,而且存储在服务器端,所以安全性高。这是会议。
问题来了。基于HTTP协议的无状态特性,服务器根本不知道访问者是谁。那么上面的Cookie就起到了桥梁的作用。
我们可以为每个客户端的Cookie分配一个唯一的id,这样当用户访问时,服务器将知道是谁通过Cookie访问的。然后根据不同Cookie的id,在服务器上保存一段时间的一些私密信息,比如“账号密码”等等。
总结一下:Cookie弥补了无状态HTTP的不足,让服务器知道谁来了;然而,Cookie是以文本的形式存储在本地的,其自身的安全性较差;所以我们使用Cookie来识别不同的用户,并在会话中存储私有信息和超过4096字节的文本。
另外,上面说的Cookie和Session其实都是常见的东西,并不局限于语言和框架。
会话是存储在服务器中的键值对。
Django #中与会话相关的方法获取、设置和删除会话中的数据
request.session[k1]
request.session.get(k1 ,无)
request.session[k1]=123
如果request.session.setdefault (k1 ,123) #存在,则不会设置它。
del request.session[k1]
#所有键、值、键值对
request . session . key()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
#会话会话的密钥
请求.会话.会话_密钥
# 将所有会议失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查会话会议的键在数据库中是否存在
request.session.exists(会话密钥)
# 删除当前会话的所有会议数据
request.session.delete()
# 删除当前的会话数据并删除会话的饼干。
request.session.flush()
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout()函数中就会调用它。
# 设置会话会议和饼干的超时时间
请求.会话.设置_到期(值)
* 如果价值是个整数,会话会在些秒数后失效。
* 如果价值是个数据时间或时间增量,会话就会在这个时间后失效。
* 如果价值是0,用户关闭浏览器会议就会失效。
* 如果价值是无,会话会依赖全局会议失效策略100 .会议流程解析
姜戈中的会议配置姜戈中默认支持会话,其内部提供了5种类型的会议供开发者使用。settings.py文件中配置
1.数据库会议
SESSION _ ENGINE= django。贡献。会话。后端。db #引擎(默认)
2.缓存会议
SESSION _ ENGINE= django。贡献。会话。后端。缓存 #引擎
会话缓存别名=默认 #使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3.文件会议
SESSION _ ENGINE= django。贡献。会话。后端。文件 #引擎
会话文件路径=无#缓存文件路径,如果为没有,则使用临时文件模块获取一个临时地址tempfile.gettempdir()
4.缓存数据库
SESSION _ ENGINE= django。贡献。会话。后端。cached _ db #引擎
5.加密饼干会话
SESSION _ ENGINE= django。贡献。会话。后端。签名的cookies #引擎
其他公用设置项:
会话饼干名称=会话id #会话的甜饼干保存在浏览器上时的钥匙,即:会话id=随机字符串(默认)
SESSION _ COOKIE _ PATH=/ # SESSION的甜饼干保存的路径(默认)
会话_ COOKIE _域=无#会话的甜饼干保存的域名(默认)
SESSION_COOKIE_SECURE=False #是否安全超文本传输协议传输cookie(默认)
SESSION_COOKIE_HTTPONLY=True #是否会议的甜饼干只支持超文本传送协议(超文本传输协议的缩写)传输(默认)
SESSION _ COOKIE _ AGE=1209600 # SESSION的甜饼干失效日期(2周)(默认)
SESSION _ EXPIRE _ AT _ BROWSER _ CLOSE=False #是否关闭浏览器使得会议过期(默认)
SESSION _ SAVE _ EVERY _ REQUEST=False #是否每次请求都保存会话,默认修改之后才保存(默认)CBV中加装饰器相关血容量实现的登录视图
类登录视图(视图):
定义获取(自身,请求):
处理得到请求
返回渲染(请求,《login.html》)
定义发布(自己,请求):
处理邮政请求
用户=请求. POST.get(用户)
pwd=请求POST.get(pwd )
如果用户==亚历克斯和pwd==alex1234 :
next_url=请求. GET.get(下一个)
# 生成随机字符串
# 写浏览器甜饼干会话id:随机字符串
# 写到服务端会话:
# {
# 随机字符串:{ 用户:亚历克斯 }
# }
request.session[用户]=用户
if next_url:
返回重定向(下一个网址)
否则:
返回重定向(/index/)
返回渲染(请求,《login.html》)要在血容量视图中使用我们上面的检查_登录装饰器,有以下三种方式:
从姜戈。utils。装饰者导入方法_装饰者
1.加在血容量视图的得到或邮政方法上从姜戈。utils。装饰者导入方法_装饰者
班级主页视图(视图):
定义调度(自身,请求,*参数,*kwargs):
返回超级(HomeView,self).派遣(请求,*参数,*克沃格)
定义获取(自身,请求):
返回渲染(请求,《home.html》)
@method_decorator(检查_登录)
定义发布(自己,请求):
打印(主页视图发布方法.)
返回重定向(/index/)2 .加在派遣方法上从姜戈。utils。装饰者导入方法_装饰者
班级主页视图(视图):
@method_decorator(检查_登录)
定义调度(自身,请求,*参数,*kwargs):
返回超级(HomeView,self).派遣(请求,*参数,*克沃格)
定义获取(自身,请求):
返回渲染(请求,《home.html》)
定义发布(自己,请求):
打印(主页视图发布方法.)
返回重定向(/index/)因为血容量中首先执行的就是派遣方法,所以这么写相当于给得到和邮政方法都加上了登录校验。
3.直接加在视图类上,但方法_装饰者必须传名字关键字参数如果得到方法和邮政方法都需要登录校验的话就写两个装饰器。
从姜戈。utils。装饰者导入方法_装饰者
@method_decorator(check_login,name=get )
@method_decorator(check_login,name=post )
班级主页视图(视图):
定义调度(自身,请求,*参数,*kwargs):
返回超级(HomeView,self).派遣(请求,*参数,*克沃格)
定义获取(自身,请求):
返回渲染(请求,《home.html》)
定义发布(自己,请求):
打印(主页视图发布方法.)
返回重定向(/index/)
补充跨站点请求伪造代币相关装饰器在血容量只能加到派遣方法上,或者加在视图类上然后名字参数指定为派遣方法。
备注:
csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便设置中没有设置全局中间件csrf_exempt,取消当前函数防跨站请求伪造功能,即便设置中设置了全局中间件。来自django.views.decorators.csrf导入csrf_exempt,csrf_protect
从姜戈。utils。装饰者导入方法_装饰者
班级主页视图(视图):
@method_decorator(csrf_exempt)
定义调度(自身,请求,*参数,*kwargs):
返回超级(HomeView,self).派遣(请求,*参数,*克沃格)
定义获取(自身,请求):
返回渲染(请求,《home.html》)
定义发布(自己,请求):
打印(主页视图发布方法.)
返回重定向(/index/)或者
从django.views.decorators.csrf导入csrf_exempt,csrf_protect
从姜戈。utils。装饰者导入方法_装饰者
@method_decorator(csrf_exempt,name=dispatch )
班级主页视图(视图):
定义调度(自身,请求,*参数,*kwargs):
返回超级(HomeView,self).派遣(请求,*参数,*克沃格)
定义获取(自身,请求):
返回渲染(请求,《home.html》)
定义发布(自己,请求):
打印(主页视图发布方法.)
返回重定向(/index/)
饼干和会议练习示例说明:app01使用饼干,应用程序02使用会议
资源定位符路由
从django.conf.urls导入全球资源定位器(Uniform Resource Locator)
来自姜戈. contrib导入管理
从app01将视图导入为第五颅神经的眼支
从app02将视图导入为v2
urlpatterns=[
url(r^admin/,管理网站网址),
url(r^app01/login/$,v1.login),
url(r^app01/home/$,v1.home),
url(r^app01/index/$,v1.index),
url(r^app01/logout/$,v1.logout),
url(r^app02/login/$,v2.login),
url(r^app02/home/$,v2.home),
url(r^app02/index/$,v2.index),
url(r^app02/logout/$,v2.logout),
url(r^app02/userinfo/$,v2.userinfo.as_view()),
]urls.py
模板app01目录下:
# home.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题主页/标题
/头
身体
氕这是家页面/h1
a href=app01/logout 注销/a
/body
/html
# index.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题索引/标题
/头
身体
氕这是索引页面/h1
/body
/html
# login.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题索引/标题
/头
身体
氕这是注册页面/h1
表单操作={{ request.get_full_path }} 方法=post
{% csrf_token %}
p
用户名:
输入类型=文本名称=用户
/p
p
密码:
输入类型=文本名称=密码
/p
输入类型=提交值=提交
/表单
/body
/html app01目录下的超文本标记语言文件
app02目录下:
# home.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题主页/标题
/头
身体
氕这是{{用户}}主页面/h1
a href=/app02/logout/注销/a
/body
/html
# index.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题索引/标题
/头
身体
氕这是索引页面/h1
/body
/html
# login.html
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题索引/标题
/头
身体
氕这是注册页面/h1
表单操作={{ request.get_full_path }} 方法=post
{% csrf_token %}
p
用户名:
输入类型=文本名称=用户
/p
p
密码:
输入类型=文本名称=密码
/p
输入类型=提交值=提交
/表单
/body
/html app02目录下的超文本标记语言文件
饼干版登录验证
快捷方式导入渲染,重定向
#在此创建您的观点。
从函数工具导入包装
定义检查_登录(函数):
@wraps(func) #装饰器修复技术
def inner(request,*args,*kwargs):
# 已经登录过的继续执行
ret=请求。get _ signed _ cookie( is _ log in ,默认=0 ,salt=颜佳)
if ret==1 :
return func(request,*args,**kwargs)
# 没有登录过的跳转到登录页面
否则:
# 获取当前访问的统一资源定位器
next_url=request.path_info
打印(下一个网址)
返回重定向(/app01/login/?next={} .格式(下一个网址))
返回内部
定义登录(请求):
打印(request.get_full_path()) #获取当前请求的路径和参数
print(request.path_info) #获取当前请求的路径
if request.method==POST :
用户=请求. POST.get(用户)
pwd=请求POST.get(pwd )
# 从统一资源定位器里面取到然后参数
next_url=请求. GET.get(下一个)
如果user==root 且pwd==root :
# 登录成功
# 告诉浏览器保存一个键值对
if next_url:
rep=redirect(next_url) #得到一个响应对象
否则:
rep=redirect(/app01/home/)
# 设置加盐的甜饼干
rep . set _ signed _ cookie( is _ log in , 1 ,salt=颜佳,max_age=30) #设置超时时间默认单位是秒
退货代表
返回渲染(请求, app01/login.html )
定义主页(请求):
# 从请求的甜饼干中查找有没有甜饼干
# 取加盐过的甜饼干
ret=请求。get _ signed _ cookie( is _ log in ,默认=0 ,salt=颜佳)
# ret=请求COOKIES.get(is_login ,0)
if ret==1 :
# 表示已经登录过
返回渲染(请求, app01/home.html )
否则:
返回重定向(/app01/login/)
@检查_登录
定义索引(请求):
返回渲染(请求, app01/index.html )
# 注销函数
定义注销(请求):
# 如何删除甜饼干
rep=redirect(/app01/login/)
rep.delete_cookie(is_login )
返回repCookie版登录验证
会议版登录验证
快捷方式导入渲染,重定向
从姜戈。utils。装饰者导入方法_装饰者
从框架导入视图
#在此创建您的观点。
从函数工具导入包装
定义检查_登录(函数):
@wraps(func) #装饰器修复技术
def inner(request,*args,*kwargs):
ret=请求。会话。get( is _ log in )
# 1.获取甜饼干中的随机字符串
# 2.更具随机字符串去数据库取会话数据———解密——— 反序列化成字典
# 3.在字典里面根据是_登录取具体的数据
if ret==1 :
# 已经登录过的继续执行
return func(request,*args,**kwargs)
# 没有登录过的跳转到登录页面
否则:
# 获取当前访问的统一资源定位器
next_url=request.path_info
打印(下一个网址)
返回重定向(/app02/login/?next={} .格式(下一个网址))
返回内部
定义登录(请求):
if request.method==POST :
用户=请求. POST.get(用户)
pwd=请求POST.get(pwd )
# 从统一资源定位器里面取到然后参数
next_url=请求. GET.get(下一个)
如果user==root 且pwd==root :
# 登录成功
# 告诉浏览器保存一个键值对
if next_url:
rep=redirect(next_url) #得到一个响应对象
否则:
rep=redirect(/app02/home/)
# 设置会议
request.session[is_login]=1
request.session[用户]=用户
request.session.set_expiry(7)
退货代表
返回渲染(请求, app02/login.html )
@检查_登录
定义主页(请求):
user=request.session.get(user )
return render(request, app02/home.html ,{user: user})
@检查_登录
定义索引(请求):
返回渲染(请求, app02/index.html )
# 注销函数
定义注销(请求):
# 只删除会议数据
request.session.delete()
# 如何删除会议数据和甜饼干
request.session.flush()
返回重定向(/app02/login/)
# 给血容量视图加装饰器
类用户信息(视图。查看):
@method_decorator(检查_登录)
定义获取(自身,请求):
render (request, app02/userinfo.html )会话版本登录验证
生活是一条无名的河,你必须或浅或深地穿过它;生活是一杯无色的茶,无论苦还是甜,你都应该喝下去;生活是一首无所畏惧的歌,你要唱高或低。
转载请联系作者授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。