响应报文:由协议版本、状态码(status code)、原因短语(reason phrase)、响应首部和响应主体组成。
有时想附加或者修改某个首部字段。比如,生成状态码3XX的重定向响应,需要将首部中的LOCATION字段设置为重定向的目标URL:
重定向(Redirect), 向访问location:5000/hi,加载后url变成location:5000/hello的重定向流程:
需要重定向情况:当某个用户在没有经过认证的情况下访问需要登录后才能访问的资源时,程序通常会重定向到登录页面。Flask提供了一些辅助工具,除了像前面手动生成302响应,还能用redirect()
错误响应,访问localtion:5000/brew/coffee 会返回418错误响应:
在abort()函数中传入状态码即可返回对应的错误响应,
ps:abort()函数前不需要使用return语句,但一旦函数被调用,函数后的代码不会被执行。
响应格式
不同的响应数据格式需要设置不同的MIME类型,在首部的Content-Type字段中定义,默认为text/html: charset=utf-8
make_request():可使用其他MIME类型,该方法生成响应对象,传入响应的主体作为参数,然后使用响应对象的mimetype属性设置类型。常用的数据格式有纯文本(text/plain)、HTML(text/html)、XML(application/xml)和JSON(application/json)。
html:常常包含吩咐的信息,可以直接将html嵌入页面中,处理起来比较方便,默认的数据类型。
xml:可扩展标记语言,一种简单灵活的文本格式,被设计用来存储和交换数据。可以弥补HTML的不足:对于仅仅需要数据的请求来说,html提供的信息太过丰富,而且不易于重用。HTML中的标签用于显示内容,XML中的标签只用于定义数据。XML一般作为ajax请求的响应个数,或是Web API的响应格式.
JSON:javascript对象表示法,一种流行的、轻量的数据交换格式。弥补了XML的不足:XML有较高的重用性,但相对其他文档格式来说,体积稍大,处理和解析的速度较慢。JSON轻量,简洁,容易阅读和解决。JSON结构基于”键值对的集合“和”有序的值列表“。
使用jsonify可将字典、列表或元组序列化为json字符串:
or
http://localhost:5000/foo 返回:
另外:函数默认生成200响应,耶可以通过附加状态码自定义响应类型:
cookie
http是无状态协议,就是说:在一次请求响应结束后,服务器不会留些任何对于对方状态的信息。但比如用户的登录状态,需要被记住,才能根据用户的状态返回不同的响应,cookie通过在请求和响应报文中添加数据来保存客户端的状态信息。浏览器再一定时间内保存,并在下一次向同一个服务器发送请求时附带这些数据。
set_cookie():需要先用make_request手动生成一个响应对象,传入响应主体作为参数。
获取:request.cookies.get(‘name’, ‘human’) 取不到值时,默认human.
安全的cookie
用户登录认证后,用户名等信息会存储在浏览器中,在浏览器中手动添加和修改cookie是很容易的事,恶意用户就可以通过伪造cookie的内容来获得对网站的权限,冒用他人的账户。flask提供了session对象用来将cookie数据加密存储。
设置程序密钥:app.secret_key=‘secret string’
模拟用户认证
通过判断session是否存在loged-in键来判断用户是否认证,使用session对象添加cookie时,会使用程序的密钥对其进行签名,签名后的数据存储在session的cookie里,且用户无法修改它。
默认情况下,session cookie会在用户关闭浏览器时删除,通过将session.permanent属性设为true将session的有效期延长为Flask。permanent_session_lifetime属性值对应的datetime.timedelta对象,也可通过配置变量PERMANET_SESSION_LIFETIME设置,默认31天。
attention:
尽管session对象会对cookie进行签名并加密,但这种方式仅能确保session内容不会被篡改,加密后的数据借助工具仍然可以轻易读取(即使不知道密钥)。因此。不能再session中存储敏感信息,比如用户密码。
获取上一个url
除了自动从referrer获取,更常见的是在url中手动加入包含当前页面url的参数,这个查询参数一般命名为next。foo和bar视图的返回值中
在程序内部只需要使用相对URL,request.full_path获取当前页面的完整路径。
return redirect(request.args.get(‘next’))
return redirect(request.args.get(‘next’,url_for(‘hello’)))
当next参数为空时,重定向到hello视图。
若referrer和next为空时,重定向到默认的视图。
上面的is_safe_url是对url进行安全验证,防止next被篡改带来的失误。
request.host_url获取程序内的主机url,urljoin将目标url转换为绝对url。
最后将目标的url模式和主机地址进行校验,确保只有属于程序内部的URL才能被返回。
使用ajax,使用jQuery函数ajax发送AJAX请求
返回“局部数据”:三种类型:
a. 纯文本或局部HTML模板
b. JSON数据:使用jsonify将字典、列表或元组序列化为json字符串
c. 空值:return ‘’, 204 (无内容)
HTTP服务器端推送
客户端拉取: 服务器端始终处于被动的应答状态,只有客户端发出请求的情况下,服务器端才会返回请求(刷新页面或单击加载按钮)
服务器端的主动推送:聊天室由很多用户,当某个用户发送信息后,服务器接收到这个请求,然后把信息推送到聊天室的所有用户。(类似:股市行情监控,多人游戏等
实现服务器推送数据的技术:
ps:轮询会造成服务器资源上的浪费,增加服务器的负担,而且会让用户的设备耗费更多的电量。
注入攻击:系统命令注入,SQL注入,NoSQL注入,ORM(对象关系映射)注入。
只要防范:
a. 使用ORM一定程度上避免SQL注入问题
b. 验证输入类型。比如某个视图函数接收整型id来查询,那么就在URL规则中限制URL变量为整型。
c. 参数化查询,在构造SQL语句时比卖你使用拼接字符串或字符串格式化。
d. 转义特殊字符
XSS攻击(cross-site scripting):网页中注入代码,
若用户在传入参数时传入一段js代码:
?name=
当客户端收到响应后,浏览器解析到会打开一个弹窗,这个能窃取用户的cookie和其他敏感数据,重定向到钓鱼网站,执行转帐,发布广告信息,用css插入图片等。
主要防范措施:
a. HTML转义,比如使用Jinja2提供的escape()函数对用户传入的数据进行转义,转义后,文本中的特殊字符,如<,>会转义成HTML实体,用户传入的js代码会以文本形式显示。
b. 验证用户输入:类型验证
CSRF攻击:跨站请求伪造
用户登录网站A,登录信息存储到cookie中,再登录网站B,B可向A服务器发送一个伪造的请求,该用户的信息便会遭到篡改。(cookie:发送请求时,只要浏览器中保存了对应的cookie,服务器端就会认为用户已经处在登录状态。)
防范措施:
a. 正确使用http方法get post
b. CSRF令牌校验
当处理非get请求,关键在于是否来自自己的网站,但referrer也可被修改或伪造,一般做法通过在客户端页面中加入伪随机数来防止攻击,即token
把伪随机数添加到表当中的隐藏字段里和session变量(cookie)中,和表单数据一起提交。在服务器端对伪随机数进行校验证,若表单中的token与session中的相同,说明是自己的网站(token在一定时间内过期)