1、基本操作

Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)

在后台设置cookie:

class IndexHanlder(tornado.web.RequestHandler):
def get(self):
print(self.cookies) #获取http请求中携带的浏览器中的所有cookie
print(self.get_cookie("k1")) # 获取浏览器中的cooki
self.set_cookie("k1","v1") #为浏览器设置cookie

在前端(浏览器上使用JavaScript):

document.cookie               #获取浏览器中所有的cookie
document.cookie.split(";") #获取浏览器中具体某一个cookie,需要先分割,再操作
document.cookie = "k1=999" #设置cookie

由于Cookie保存在浏览器端,所以在浏览器端也可以使用JavaScript来操作Cookie:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>123</h1>
</body>
<script>
/*设置cookie,指定秒数过期*/
function setCookieBySeconds(name,value,expires){
var current_date = new Date(); //获取当前时间
current_date.setSeconds(current_date.getSeconds() + expires);
document.cookie = name + "= "+ value +";expires=" + current_date.toUTCString();
}
/*设置cookie,指定天数过期*/
function setCookieByDays(name,value,expires){
var current_date = new Date(); //获取当前时间
current_date.setDate(current_date.getDate() + expires);
document.cookie = name + "= "+ value +";expires=" + current_date.toUTCString();
}
</script>
</html>

2、加密cookie(签名)

Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:

def _create_signature_v1(secret, *parts):
hash = hmac.new(utf8(secret), digestmod=hashlib.sha1)
for part in parts:
hash.update(utf8(part))
return utf8(hash.hexdigest()) # 加密
def _create_signature_v2(secret, s):
hash = hmac.new(utf8(secret), digestmod=hashlib.sha256)
hash.update(utf8(s))
return utf8(hash.hexdigest()) def create_signed_value(secret, name, value, version=None, clock=None,
key_version=None):
if version is None:
version = DEFAULT_SIGNED_VALUE_VERSION
if clock is None:
clock = time.time timestamp = utf8(str(int(clock())))
value = base64.b64encode(utf8(value))
if version == 1:
signature = _create_signature_v1(secret, name, value, timestamp)
value = b"|".join([value, timestamp, signature])
return value
elif version == 2:
# The v2 format consists of a version number and a series of
# length-prefixed fields "%d:%s", the last of which is a
# signature, all separated by pipes. All numbers are in
# decimal format with no leading zeros. The signature is an
# HMAC-SHA256 of the whole string up to that point, including
# the final pipe.
#
# The fields are:
# - format version (i.e. 2; no length prefix)
# - key version (integer, default is 0)
# - timestamp (integer seconds since epoch)
# - name (not encoded; assumed to be ~alphanumeric)
# - value (base64-encoded)
# - signature (hex-encoded; no length prefix)
def format_field(s):
return utf8("%d:" % len(s)) + utf8(s)
to_sign = b"|".join([
b"",
format_field(str(key_version or 0)),
format_field(timestamp),
format_field(name),
format_field(value),
b'']) if isinstance(secret, dict):
assert key_version is not None, 'Key version must be set when sign key dict is used'
assert version >= 2, 'Version must be at least 2 for key version support'
secret = secret[key_version] signature = _create_signature_v2(secret, to_sign)
return to_sign + signature
else:
raise ValueError("Unsupported version %d" % version) # 解密
def _decode_signed_value_v1(secret, name, value, max_age_days, clock):
parts = utf8(value).split(b"|")
if len(parts) != 3:
return None
signature = _create_signature_v1(secret, name, parts[0], parts[1])
if not _time_independent_equals(parts[2], signature):
gen_log.warning("Invalid cookie signature %r", value)
return None
timestamp = int(parts[1])
if timestamp < clock() - max_age_days * 86400:
gen_log.warning("Expired cookie %r", value)
return None
if timestamp > clock() + 31 * 86400:
# _cookie_signature does not hash a delimiter between the
# parts of the cookie, so an attacker could transfer trailing
# digits from the payload to the timestamp without altering the
# signature. For backwards compatibility, sanity-check timestamp
# here instead of modifying _cookie_signature.
gen_log.warning("Cookie timestamp in future; possible tampering %r",
value)
return None
if parts[1].startswith(b""):
gen_log.warning("Tampered cookie %r", value)
return None
try:
return base64.b64decode(parts[0])
except Exception:
return None def _decode_fields_v2(value):
def _consume_field(s):
length, _, rest = s.partition(b':')
n = int(length)
field_value = rest[:n]
# In python 3, indexing bytes returns small integers; we must
# use a slice to get a byte string as in python 2.
if rest[n:n + 1] != b'|':
raise ValueError("malformed v2 signed value field")
rest = rest[n + 1:]
return field_value, rest rest = value[2:] # remove version number
key_version, rest = _consume_field(rest)
timestamp, rest = _consume_field(rest)
name_field, rest = _consume_field(rest)
value_field, passed_sig = _consume_field(rest)
return int(key_version), timestamp, name_field, value_field, passed_sig def _decode_signed_value_v2(secret, name, value, max_age_days, clock):
try:
key_version, timestamp, name_field, value_field, passed_sig = _decode_fields_v2(value)
except ValueError:
return None
signed_string = value[:-len(passed_sig)] if isinstance(secret, dict):
try:
secret = secret[key_version]
except KeyError:
return None expected_sig = _create_signature_v2(secret, signed_string)
if not _time_independent_equals(passed_sig, expected_sig):
return None
if name_field != utf8(name):
return None
timestamp = int(timestamp)
if timestamp < clock() - max_age_days * 86400:
# The signature has expired.
return None
try:
return base64.b64decode(value_field)
except Exception:
return None def get_signature_key_version(value):
value = utf8(value)
version = _get_version(value)
if version < 2:
return None
try:
key_version, _, _, _, _ = _decode_fields_v2(value)
except ValueError:
return None return key_version

五、Session(依赖于cookie)

由于cookie中需要保存客户的很多信息,而且如果信息很多的话,服务端与客户端交互的时候也浪费流量,所以我们需要用很少的一段字符串来保存很多的信息,这就是我们所要引进的session。

cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗    考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能    考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以个人建议:    将登陆信息等重要信息存放为SESSION    其他信息如果需要保留,可以放在COOKIE中

 (1)利用session实现用户验证

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloop
import hashlib
import time
li = {}
class IndexHanlder(tornado.web.RequestHandler):
def get(self):
obj = hashlib.md5()
obj.update(bytes(str(time.time()),encoding="utf-8"))
random_str = obj.hexdigest()
li[random_str]={}
li[random_str]["k1"]=123
li[random_str]["k2"]=456
li[random_str]["is_login"]=True
self.set_cookie("qqqqqq",random_str)
self.write("成功设置cookie")
def post(self, *args, **kwargs):
pass class ManagerHanlder(tornado.web.RequestHandler):
def get(self):
random_str = self.get_cookie("qqqqqq",None)
current_user_info = li.get(random_str,None)
if not current_user_info:
self.redirect("/index")
else:
if li[random_str]["is_login"]:
self.write("欢迎")
else:
self.redirect("/index")
def post(self, *args, **kwargs):
pass settings={
"template_path":"tpl",
"static_path":"st",
"cookie_secret":"123"
} class IndeHanlder(tornado.web.RequestHandler):
def get(self):
self.render("1.html")
application = tornado.web.Application([
(r"/index", IndexHanlder),
(r"/manager", ManagerHanlder),
],**settings) if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()

 (2)利用session验证用户精简版

#!/usr/bin/env/python
# -*- coding:utf-8 -*-
import tornado.web container = {}
# container = {
# # "第一个人的随机字符串":{},
# # "第一个人的随机字符串":{'k1': 111, 'parents': '你'},
# } class Session:
def __init__(self, handler):
self.handler = handler
self.random_str = None def __genarate_random_str(self):
import hashlib
import time
obj = hashlib.md5()
obj.update(bytes(str(time.time()), encoding='utf-8'))
random_str = obj.hexdigest()
return random_str def __setitem__(self, key, value):
# 在container中加入随机字符串
# 定义专属于自己的数据
# 在客户端中写入随机字符串
# 判断,请求的用户是否已有随机字符串
if not self.random_str:
random_str = self.handler.get_cookie('__kakaka__')
if not random_str:
random_str = self.__genarate_random_str()
container[random_str] = {}
else:
# 客户端有随机字符串
if random_str in container.keys():
pass
else:
random_str = self.__genarate_random_str()
container[random_str] = {}
self.random_str = random_str container[self.random_str][key] = value
self.handler.set_cookie("__kakaka__", self.random_str) def __getitem__(self, key):
# 获取客户端的随机字符串
# 从container中获取专属于我的数据
# 专属信息【key】
random_str = self.handler.get_cookie("__kakaka__")
if not random_str:
return None
# 客户端有随机字符串
user_info_dict = container.get(random_str,None)
if not user_info_dict:
return None
value = user_info_dict.get(key, None)
return value
class BaseHandler(tornado.web.RequestHandler):
def initialize(self):
self.session = Session(self)
class IndexHandler(BaseHandler):
def get(self):
if self.get_argument('u',None) in ['alex','eric']:
self.session['is_login'] = True
self.session['name'] =self.get_argument('u',None)
print(container)
else:
self.write('请你先登录')
class MangerHandler(BaseHandler):
def get(self):
val = self.session['is_login']
if val:
self.write(self.session['name'])
else:
self.write('登录失败')
class LoginHandler(BaseHandler):
def get(self,*args,**kwargs):
self.render('login.html',status="")
def post(self, *args, **kwargs):
user = self.get_argument('user',None)
pwd = self.get_argument('pwd',None)
code = self.get_argument('code',None)
check_code = self.session['CheckCode']
if code.upper() == check_code.upper():
self.write('验证码正确')
else:
self.render('login.html',status ='验证码错误')
class CheckCodeHandler(BaseHandler):
def get(self,*args,**kwargs):
import io
import check_code
mstream = io.BytesIO()
img, code = check_code.create_validate_code()
img.save(mstream,'GIF')
self.session['CheckCode']=code
self.write(mstream.getvalue())
class CsrfHandler(BaseHandler):
def get(self,*args,**kwargs):
self.render("csrf.html")
def post(self, *args, **kwargs):
self.write("hahahahaah") settings = {
'template_path':'views',
'static_path':'static',
"xsrf_cookies":True
}
application = tornado.web.Application([
(r'/index',IndexHandler),
(r'/manger',MangerHandler),
(r'/login',LoginHandler),
(r'/check_code',CheckCodeHandler),
(r'/csrf',CsrfHandler),
],**settings) if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()

  

 

cookie的更多相关文章

  1. 超大 Cookie 拒绝服务攻击

    有没有想过,如果网站的 Cookie 特别多特别大,会发生什么情况? 不多说,马上来试验一下: for (i = 0; i < 20; i++) document.cookie = i + '= ...

  2. IE10、IE11 User-Agent 导致的 ASP.Net 网站无法写入Cookie 问题

    你是否遇到过当使用一个涉及到Cookie操作的网站或者管理系统时,IE 6.7.8.9下都跑的好好的,唯独到了IE10.11这些高版本浏览器就不行了?好吧,这个问题码农连续2天内遇到了2次.那么,我们 ...

  3. 解决cookie跨域访问

    一.前言 随着项目模块越来越多,很多模块现在都是独立部署.模块之间的交流有时可能会通过cookie来完成.比如说门户和应用,分别部署在不同的机器或者web容器中,假如用户登陆之后会在浏览器客户端写入c ...

  4. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  5. 一个诡异的COOKIE问题

    今天下午,发现本地的测试环境突然跑不动了,thinkphp直接跑到异常页面,按照正常的排错思路,直接看thinkphp的log 有一条 [ error ] [2]setcookie() expects ...

  6. [转载]Cookie/Session的机制与安全

    Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...

  7. jquery.cookie的使用

    今天想到了要为自己的影像日记增加赞的功能,并且需要用到cookie. 记得原生的js操作cookie也不是很麻烦的,但似乎jquery更简单,不过相比原生js,需要额外引入2个文件,似乎又不是很好,但 ...

  8. 跨域问题,前端主动向后台发送cookie

    跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同  http://www.baidu.com:80 和 https:/ ...

  9. 【流量劫持】沉默中的狂怒 —— Cookie 大喷发

    精简版:http://www.cnblogs.com/index-html/p/mitm-cookie-crack.html 前言 上一篇文章 讲解了如何借助前端技术,打造一个比 SSLStrip 更 ...

  10. 好好了解一下Cookie

    Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前最新 ...

随机推荐

  1. VS2010中dumpbin工具的使用

    用VS2010生成的.obj文件..lib库..dll库..exe执行文件,如果想查看其中这些文件或库包含了哪些函数以及相关的信息(符号清单),可以通过VS2010自带的dumpbin工具来完成. d ...

  2. MongoDB学习笔记(一) MongoDB介绍及安装(摘)

    MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mongo使用C++开发.Mongo的官方网 ...

  3. JqueryDataTable的使用(.Net平台)

    上一篇随笔提到了MvcPager,最近用到了一款前端JQ插件------DataTable(简称DT),很好用. DT是一款前端插件,和后端完全分离开,就这点来看,我就特别喜欢. 一.使用DT,需要以 ...

  4. Google C++单元测试框架GoogleTest---值参数化测试

    值参数化测试允许您使用不同的参数测试代码,而无需编写同一测试的多个副本. 假设您为代码编写测试,然后意识到您的代码受到布尔参数的影响. TEST(MyCodeTest, TestFoo) { // A ...

  5. SQLSERVER 2012 收缩日志

    select log_reuse_wait_desc from sys.databases where name='tfs_CARDLANWEB' backup log tfs_CARDLANWEB ...

  6. 简历生成平台项目开发-STEP5初步界面demo实现

    谭卓因为暑期实习,去杭州实习了,走之前在git上上传了一些文档(https://github.com/USTC-CV-creator/),项目到目前为止,前端demo已经做好,后台接收请求生成PDF部 ...

  7. 织梦Dedecms使用Nginx的安全设置

    首先需要说明的是,任何程序都是有漏洞的,我们需要做好一些必要的防范,来减少由于程序漏洞造成的损失.织梦的漏洞多,这个是很多人的想法.不过大家如果做好了织梦系统的文件夹权限什么的设置,很多漏洞也是用不上 ...

  8. 树莓派3B更新软件

    因为软件是要不断更新的,所以半个月或者一个月要升级一下软件 升级软件非常简单 在终端或者SSH里输入 sudo apt-get update && apt-get upgrade -y ...

  9. 6-2 sed 命令

    1. sed : stream editor,流编辑器 是处理纯ASICC纯文本,按行琢行操作的. 编辑器有两种,行编辑器和全屏编辑器 sed:默认不编辑原文件,仅对模式空间中的数据做处理,而后.处理 ...

  10. 通过中看不中用的代码分析Ioc容器,依赖注入....

    /** * 通过生产拥有超能力的超人实例 来理解IOC容器 */ //超能力模组接口 interface SuperModuleInterface{ public function activate( ...