当前位置: 首页 > article >正文

url编码之urldecode,urlencode/python自带的http服务/cookie,session,token

目录

  • 为什么要进行decode || encode
  • requests包的处理
  • urllib.parse
    • urlencode
    • quote
    • urlencode,unquote
    • requests转码的效果
  • Python开启自带http服务
  • 会话跟踪技术
    • Cookie和session
      • cookie
        • 什么是cookie
        • cookie原理
        • Django中操作Cookie
      • Session
        • Session的由来
        • Django中Session相关方法
    • Token
      • 基于服务器验证方式暴露的一些问题
      • 基于Token的验证原理
      • Tokens的优势
        • 无状态、可扩展
        • 安全性
        • 可扩展性
        • 多平台跨域

为什么要进行decode || encode

URL参数字符串中使用key=value键值对这样的形式来传参,键值对之间以&符号分隔,如果value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。

requests包的处理

在用Python+requests做接口自动化过程中,http协议在发送url的时候,是以urlencode的编码格式传过去的,通常requests库会自动处理。
在这里插入图片描述

@staticmethoddef _encode_params(data):"""Encode parameters in a piece of data.Will successfully encode parameters when passed as a dict or a list of2-tuples. Order is retained if data is a list of 2-tuples but arbitraryif parameters are supplied as a dict."""if isinstance(data, (str, bytes)):return dataelif hasattr(data, "read"):return dataelif hasattr(data, "__iter__"):result = []for k, vs in to_key_val_list(data):if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):vs = [vs]for v in vs:if v is not None:result.append((k.encode("utf-8") if isinstance(k, str) else k,v.encode("utf-8") if isinstance(v, str) else v,))# 此处对params进行urlencodereturn urlencode(result, doseq=True)else:return data

urllib.parse

urllib.parse 里面4个方法:urlencode、urldecode、quote 和 unquote, 分别参数编码与解码

urlencode

# Encode a dict or sequence of two-element tuples into a URL query string.
urlencode(query, doseq=False, safe='', encoding=None, errors=None,quote_via=quote_plus)

urlencode方法能对字典编码

from urllib.parse import urlencodepayload = {"content": '<head title="test" name="xxx">',
}
print(urlencode(payload))
------------------------------------------
content=%3Chead+title%3D%22test%22+name%3D%22xxx%22%3E

quote

quote方法能对字符串编码

# quote('abc def') -> 'abc%20def'
quote(string, safe='/', encoding=None, errors=None)
from urllib.parse import quoteprint(quote('https://www.xxx.com?content=<head title="test" name="xxx">+'))
-----------------------------------------------------
https%3A//www.xxx.com%3Fcontent%3D%3Chead%20title%3D%22test%22%20name%3D%22xxx%22%3E%2B

urlencode,unquote

requests转码的效果

import requests
from urllib3 import disable_warningsurl = 'https://www.xxx.com?content=<head title="test" name="xxx">+'
disable_warnings()
res = requests.get(url, timeout=0.1, verify=False)
print(res.url)---------------------------------------------------
/?content=%3Chead%20title=%22test%22%20name=%22xxx%22%3E+

Python开启自带http服务

  1. cd 到要展示的目录
  2. python3 -m http.server 8000 表示在8000端口开启服务
  3. 通过本机ip:port查看目录下的网页文件,若无index.html则会显示目录下的文件

快捷方便的开启一个http服务,也可以简单的进行文件传输(sftp)

会话跟踪技术

在一个会话的多个请求中共享数据,这就是会话跟踪技术。

例如在一个会话中的请求如下: 请求银行主页:

  1. 请求登录(请求参数是用户名和密码);
  2. 请求转账(请求参数与转账相关的数据);
  3. 请求信誉卡还款(请求参数与还款相关的数据)。

在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

Cookie和session

HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!在Web开发中,使用session来完成会话跟踪,session底层依赖Cookie技术

cookie

什么是cookie

Cookie是key-value结构,类似于一个python中的字典。随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie,不能跨域)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

cookie原理

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

Django中操作Cookie
  1. 获取Cookie

    request.COOKIES['key']
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    

    参数:
    default: 默认值
    salt: 加密盐
    max_age: 后台控制过期时间

  2. 设置Cookie

    rep = HttpResponse(...)
    rep = render(request, ...)
    rep.set_cookie(key,value)
    rep.set_signed_cookie(key,value,salt='加密盐')
    

    参数:
    key, 键

    value=‘’, 值

    max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是None ,这个cookie会延续到浏览器关闭为止

    expires=None, 超时时间(IE requires expires, so set it if hasn’t been already.)

    path=‘/’, Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。

    domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取

    secure=False, 浏览器将通过HTTPS来回传cookie

    httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

  3. 删除Cookie

    def logout(request):rep = redirect("/login/")rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值return rep
    

Session

Session的由来

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

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

Django中Session相关方法
# 获取、设置、删除Session中数据
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
del request.session['k1']# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()# 会话session的key
request.session.session_key# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")# 删除当前会话的所有Session数据(只删数据库)
request.session.delete()# 删除当前的会话数据并删除会话的Cookie(数据库和cookie都删)。
request.session.flush() 这用于确保前面的会话数据不可以再次被用户的浏览器访问例如,django.contrib.auth.logout() 函数中就会调用它。# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)* 如果value是个整数,session会在些秒数后失效。* 如果value是个datatime或timedelta,session就会在这个时间后失效。* 如果value是0,用户关闭浏览器session就会失效。* 如果value是None,session会依赖全局session失效策略。
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎其他公用设置项:
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,默认修改之后才保存(默认)

Token

在这里插入图片描述
在这里插入图片描述
在Web领域基于Token的身份验证随处可见。在大多数使用Web API的互联网公司中,tokens 是多用户下处理认证的最佳方式。

以下几点特性会让你在程序中使用基于Token的身份验证

1.无状态、可扩展

2.支持移动设备

3.跨程序调用

4.安全

基于服务器验证方式暴露的一些问题

1.Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。

2.可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。

3.CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。

4.CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。

基于Token的验证原理

基于Token的身份验证是无状态的,不将用户信息存在服务器或Session中。

这种概念解决了在服务端存储信息时的许多问题

NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。

基于Token的身份验证的过程如下:

1.用户通过用户名和密码发送请求。

2.程序验证。

3.程序返回一个签名的token 给客户端。

4.客户端储存token,并且每次用于每次发送请求。

5.服务端验证token并返回数据。

每一次请求都需要token。token应该在HTTP的头部发送从而保证了Http请求无状态。我们同样通过设置服务器属性Access-Control-Allow-Origin:* ,让服务器能接受到来自所有域的请求。

实现思路:

在这里插入图片描述

Tokens的优势

无状态、可扩展

在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。

如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)。用户量大时,可能会造成 一些拥堵。

但是不要着急。使用tokens之后这些问题都迎刃而解,因为tokens自己hold住了用户的验证信息。

安全性

请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。

token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。

可扩展性

Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。

使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。

多平台跨域
http://www.lryc.cn/news/2414486.html

相关文章:

  • 向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读
  • bio nio aio区别_8分钟深入浅出搞懂BIO、NIO、AIO
  • 串口通信原理
  • 使用Windows自带命令diskpart管理分区
  • Openjudge 栈的基本操作
  • 【建议收藏】7 个“最佳”AI 视频生成器
  • innerHTML的作用及用法。
  • JS中的Date类
  • 从头开始认识jboss
  • 什么是ANR,如何避免ANR
  • 【文心快码】Comate安装与使用体验分享
  • zookeeper实战全面讲解(一)
  • 6、ExtJs——Ext基础架构--认识Ext.js和Ext-more.js
  • Java高级编程——多线程
  • MySQL产品(DBMS)学习总结
  • 使用Python抓取并渲染包含JavaScript的网页(PhantomJS)
  • JAVA高频216道面试题+答案!!面试必备
  • 顶刊复现:机器学习解释利器—SHAP实战【免费获取】
  • 【Windows】Windows11查看文件的md5值
  • js 文件下载的代码
  • Mybatis源码解析--Mapper代理对象
  • 【D触发器】从底层重新认识 D 触发器、建立时间和保持时间
  • apple iMac一体机 装双系统 实战! (Apple +Win 7 64bit)Good
  • EJB3.0介绍
  • axure注册码
  • matlab2015的marker,matlab中markersize什么意思
  • SQL sever 笔记
  • surfacecreated啥时被调用_JavaScript当中的this究竟是个啥?
  • 第一节:1. 美国域名中心US Domain Center是什么,为什么选择它作为建站平台
  • 城市筛选检索