【4.0】基础串联之CookieSessionToken
【HTTP协议的缺陷】
无状态、无连接、基于请求响应、基于Tcp/Ip应用层协议
【1】无状态(Stateless):
- HTTP协议是一种无状态协议,服务器不会保存请求和响应之间的状态信息。
- 这意味着每次请求都是独立的,服务器无法直接识别来自同一个用户的多个请求。
- 这样就需要使用各种机制(如Cookie、Session等)来维护用户的状态信息,以实现登录认证和保持会话等功能。
【2】无连接(Connectionless):
- HTTP协议是一种无连接协议,即每次请求与响应之间都是相互独立的,服务器处理完一个请求后就会断开连接。
- 这意味着对于每个请求都需要建立新的连接,可能会导致额外的延迟和资源消耗。
- 为了解决这个问题,引入了持久连接和管线化技术,允许在一个连接上发送多个请求和响应,减少连接建立的开销。
【3】基于请求响应(Request-Response)模型:
- HTTP协议采用请求与响应的方式进行通信。
- 客户端发送请求到服务器,服务器处理请求并返回相应的响应。
- 这种模型适用于大部分Web场景,但在一些特定情况下,如实时消息推送、服务器主动推送等,非常依赖于服务器主动发送消息给客户端,HTTP协议的请求响应模型有局限性。
【4】基于TCP/IP协议:
- HTTP协议基于TCP/IP协议栈进行通信,借助传输层的可靠性和面向连接的特性。
- 虽然TCP协议可靠,但对于某些资源密集型、高并发的场景,TCP协议的建立和连接维护会带来较大的开销。
- 另外,使用TCP协议传输数据还可能面临拥塞控制和慢启动等问题。
【MySQL】
底层:C/S架构、底层基于Socket、自己封装的协议
客户端:Navicat(c++图形化界面,实现了请求和响应协议)、pymysql(用Python语言实现了请求和响应协议)
【1】底层架构:
- C/S架构:
- MySQL采用客户端/服务器(C/S)架构。
- 这意味着在使用MySQL时,有一个MySQL服务器进程(通常称为mysqld),负责处理来自客户端的请求。
- 基于Socket:
- MySQL底层通过Socket进行网络通信。
- 客户端与服务器之间建立Socket连接,通过发送请求和接收响应来实现数据交互。
- 自己封装的协议:
- MySQL使用自定义的协议进行请求和响应的交互。
- 这个协议定义了数据包的格式、命令的编码和解析规则等。
- 客户端和服务器需要遵守这个协议才能正常进行通信。
【2】客户端工具:
- Navicat:
- Navicat是一款流行的图形化界面的MySQL客户端工具,它使用C++语言实现了MySQL的请求和响应协议。
- Navicat提供了直观的用户界面,方便用户进行数据库管理、查询、导入导出等操作。
- 它可以帮助用户更轻松地与MySQL服务器进行交互。
- pymysql:
- pymysql是一个用Python语言开发的MySQL客户端库。
- 它实现了MySQL的请求和响应协议,并提供了一组API供开发者使用。
- 通过pymysql,开发者可以使用Python编程语言来连接MySQL服务器,执行SQL语句,获取查询结果等。
- pymysql使得在Python程序中使用MySQL变得更加方便和灵活。
【3】总结起来
- MySQL采用C/S架构,底层基于Socket通信,并使用自己封装的协议进行请求和响应的交互。
- Navicat是一个图形化界面的MySQL客户端工具,通过实现请求和响应协议,提供了可视化的数据库管理功能。
- 而pymysql则是一个用Python语言实现的MySQL客户端库,使得开发者能够用Python编写程序与MySQL服务器进行交互。
【Redis】
C/S架构、底层基于Socket、自己封装的协议
Redis(Remote Dictionary Server)是一种高性能的键值对存储系统
【1】C/S架构:
- Redis采用客户端/服务器(C/S)架构。在该架构下,有一个Redis服务器进程(通常称为redis-server),负责处理客户端的请求。
- 客户端可以通过与Redis服务器建立Socket连接来发送请求,并接收响应。这种架构允许多个客户端同时访问Redis服务器,实现了高并发的处理能力。
【2】底层基于Socket:
- Redis底层通过Socket进行网络通信。客户端与服务器之间建立Socket连接,并使用TCP/IP协议进行数据传输。
- 当客户端需要发送请求给Redis服务器时,它会将请求数据打包成数据包,并通过Socket发送给服务器。服务器接收到请求后进行处理,并将响应结果发送回客户端。这样就完成了客户端与服务器之间的通信和数据交互。
【3】自己封装的协议:
- Redis使用自己封装的协议进行请求和响应的交互。该协议是基于TCP的流式协议,简洁且高效。
- Redis协议使用文本格式,请求和响应都是以文本形式进行序列化,并通过特定的命令和参数传递。客户端发送请求时,需要按照协议规定的格式进行编码,而服务器则按照协议解析请求并返回响应。
- Redis的协议支持多种类型的操作,如键值对存取、事务处理、发布订阅等。通过操作不同的命令和参数,客户端可以对Redis服务器进行灵活的控制和操作。
【4】综上所述
- Redis采用C/S架构,底层基于Socket通信,并使用自己封装的协议进行请求和响应的交互。
- 这种架构和协议设计使得Redis具有高性能、高并发和灵活的特点,适合用于缓存、会话管理、消息队列等各种场景。
【Docker】
C/S架构、底层基于Http协议、使用restful协议
【1】C/S架构:
- Docker采用客户端/服务器(C/S)架构。在该架构下,有两个核心组件:Docker客户端和Docker引擎(也称为Docker守护进程)。
- Docker客户端是用户与Docker交互的命令行工具或图形界面,负责发送指令给Docker引擎。而Docker引擎则是运行在主机上的后台进程,负责管理和执行容器化应用程序。
- Docker客户端可以通过与Docker引擎建立Socket连接来发送命令,并接收来自引擎的响应。这种架构允许用户通过客户端与Docker引擎进行通信,控制容器的创建、启动、停止等操作。
【2】底层基于HTTP协议:
- Docker引擎使用HTTP协议与Docker客户端进行通信。当Docker客户端发出命令时,它会将命令封装成HTTP请求,并通过特定的URL路径发送给Docker引擎。
- Docker引擎接收到HTTP请求后进行解析,并执行相应的操作。执行结果会以HTTP响应的形式返回给Docker客户端。
- 使用HTTP作为底层协议的好处是它简洁且易于使用,同时也方便与其他系统进行集成和通信。
【3】使用RESTful协议:
- Docker采用RESTful协议设计其API接口。REST(Representational State Transfer)是一种基于HTTP的设计风格,通过统一的资源定位符(URL)和操作方法(GET、POST等)对资源进行访问和操作。
- Docker的API将容器、镜像、网络等抽象为不同的资源,并使用HTTP的请求方式(GET、POST、PUT、DELETE等)对这些资源进行操作。
- 例如,通过发送HTTP的POST请求给特定的URL路径可以创建一个新的容器,而发送DELETE请求则可以删除指定的容器。
- RESTful风格的API设计使得Docker的接口简洁、易于理解和使用。
【4】综上所述
- Docker采用C/S架构,底层基于HTTP协议进行通信,并使用RESTful协议设计API接口。
- 这种架构和协议组合使得用户可以通过简单的命令或操作与Docker引擎进行交互,实现容器化应用程序的管理和控制。
【elasticsearch】
C/S架构、底层基于Http协议、使用restful协议
【1】C/S架构:
- Elasticsearch采用客户端/服务器(C/S)架构。在该架构中,有两个核心组件:Elasticsearch客户端和Elasticsearch服务器。
- Elasticsearch客户端是用户与Elasticsearch进行交互的接口,可以是命令行工具、编程语言的客户端库或可视化界面。它负责发送请求给Elasticsearch服务器,并解析服务器返回的响应。
- Elasticsearch服务器是运行在集群中的一个或多个节点上的进程,负责存储和索引数据,执行搜索和分析等操作。服务器接收来自客户端的请求,执行相应的操作并返回结果。
【2】底层基于HTTP协议:
- Elasticsearch的客户端和服务器之间使用HTTP协议进行通信。当客户端发送请求给服务器时,它会将请求封装成HTTP请求,并通过特定的URL路径发送给服务器。
- 服务器接收到请求后进行解析,并执行相应的操作。执行结果以HTTP响应的形式返回给客户端,包含相关的数据或错误信息。
- 基于HTTP协议的通信方式使得Elasticsearch非常容易与各种编程语言和工具进行集成。
【3】使用RESTful协议:
- Elasticsearch的API设计遵循RESTful风格。RESTful是一种在设计网络应用程序时经常使用的架构风格,它使用统一的资源定位符(URL)和HTTP方法(GET、POST、PUT、DELETE等)对资源进行操作。
- Elasticsearch将数据和功能封装为不同的资源,例如索引、文档、搜索等,每个资源都有一个唯一的URL路径来标识。
- 使用HTTP的不同方法对这些资源进行操作,例如使用GET请求获取文档,使用POST请求创建索引,使用DELETE请求删除索引等。
- 通过简洁的URL路径和HTTP方法,RESTful API使得Elasticsearch的接口易于理解和使用。
【4】总结:
- Elasticsearch采用C/S架构,底层使用HTTP协议进行通信,并提供基于RESTful风格的API。
- 这种架构和协议的组合使得用户可以通过各种客户端与Elasticsearch服务器进行交互,执行索引、搜索、聚合等数据操作,并以HTTP响应返回结果。
【一】Cookie
- 是存在于浏览器的键值对,向服务端发起请求,需要携带cookie
- 但是不安全
-
Cookie是一种存在于浏览器的键值对,用于在客户端和服务端之间传递数据。
- 当用户访问一个网站时,网站服务器可以通过在响应头中设置Set-Cookie字段,将一个或多个Cookie发送给用户的浏览器。
- 浏览器在接收到这些Cookie后,会将其保存起来。
-
每次用户向同一个网站发起请求时,浏览器会自动将该网站对应的Cookie携带在请求头中发送给服务器。
- 服务器可以通过读取这些Cookie来获取用户登录状态、保存用户的偏好设置或其他相关数据。
-
尽管Cookie在一定程度上提供了方便性,但是也存在一些安全隐患。
-
其中最主要的问题是Cookie可能被截获或篡改
- 从而导致用户的敏感信息泄露或身份被盗用。
-
因此,为了保护用户的隐私和安全
-
网站通常会采取以下措施来加强Cookie的安全性:
-
使用安全的传输协议:
-
通过使用HTTPS等安全的传输协议
-
可以确保在传输过程中的数据不会被窃听或篡改。
-
-
设置Secure标记:
-
通过在Set-Cookie字段中设置Secure属性
-
可以告知浏览器只有在使用HTTPS连接时才发送该Cookie,这样就可以避免在非安全连接中传输敏感信息。
-
-
设置HttpOnly标记:
-
通过在Set-Cookie字段中设置HttpOnly属性
-
可以告知浏览器该Cookie仅限于服务器访问,无法通过JavaScript等脚本语言获取该Cookie的值,从而防止跨站脚本攻击(XSS)。
-
-
限制Cookie的作用范围:
-
通过在Set-Cookie字段中设置Domain和Path属性
-
可以限制Cookie只在特定的域名和路径下有效,避免被其他网站滥用。
-
-
合理设置Cookie的过期时间:
- 通过设置Expires或Max-Age属性,可以控制Cookie的有效期限。一般来说
- 对于需要用户登录的会话Cookie,应设置为会话级别,即关闭浏览器后自动删除;
- 对于非会话Cookie,应设定合理的过期时间,避免Cookie长时间存在导致安全隐患。
- 通过设置Expires或Max-Age属性,可以控制Cookie的有效期限。一般来说
-
-
- 综上所述
- 虽然Cookie在实现一些功能上提供了方便性,但其安全性问题仍需注意。
- 网站开发者在使用Cookie时,应该遵循相关的安全规范,加强对用户隐私和数据的保护。
- 同时,用户在使用网站时也要注意保护自己的信息安全,避免泄露敏感信息给不可信的网站。
【二】Session
- 存在于服务器的键值对,存放在哪?
- 存放在内存/文件/MySQL/Redis
- 缺陷:
- 如果用户量很大,存储需要耗费服务器资源
-
Session是一种存在于服务器端的键值对,用于存储用户的会话信息。
-
与Cookie不同,Session数据不会存储在用户的浏览器中,而是存储在服务器端的某个地方。
-
Session的具体存储位置可以根据开发者的需求和技术选型而有所不同。
-
以下是一些常见的存储位置:
-
内存:
-
一些简单的Web服务器可以将Session数据存储在内存中。
-
这种方式读写速度较快
-
适用于小规模的应用
-
但缺点是当服务器重启或崩溃时,所有的Session数据将丢失。
-
-
-
文件系统:
-
另一种常见的方式是将Session数据存储在服务器的文件系统中。
-
每个Session被保存为一个文件,文件名通常由Session ID决定,文件内容则为Session数据的键值对。
-
这种方式适用于单服务器环境,并且可以保证Session数据持久化。
-
然而,随着用户数量的增加,文件系统读写操作的性能可能会成为瓶颈。
-
-
-
数据库(如MySQL):
-
许多Web应用选择将Session数据存储在关系型数据库中,如MySQL。
-
使用数据库作为Session存储
-
优点是数据持久性好,并且可以支持较大规模的用户量。
-
但相应地,读写数据库的开销也可能会增加一定的负载。
-
-
-
缓存数据库(如Redis):
- 一些高性能的Web应用会选择将Session数据存储在内存中的缓存数据库,如Redis。
- Redis具有高速的读写性能和良好的扩展性,适合于处理大量请求和高并发场景。
-
-
-
上述存储位置的选择应该根据实际需求和系统架构来决定。
-
对于用户量很大的情况,存储Session数据可能会耗费服务器资源。
-
为了解决这个问题,可以采取以下措施:
-
分布式架构:
- 使用多台服务器来处理请求,并将Session数据进行分布式存储,从而提高性能和可扩展性。
-
减小Session数据量:
- 只存储必要的会话信息,并避免存储大量的冗余数据,以减少服务器资源消耗。
-
合理设置Session过期策略:
- 设置合理的Session过期时间,及时清理过期的Session数据,以释放服务器资源。
-
使用缓存技术:
- 可以结合缓存数据库,如Redis,将热门的Session数据缓存在内存中,从而加快读写速度。
-
【三】Token
- 就是个字符串
- 既安全又有个人信息
- 加密字符串会携带个人信息
- 基于这种特性,契合了前后端分离
-
Token(令牌)是一个字符串,用于在前后端分离的应用中进行身份验证和授权。
-
Token本身是一种加密字符串,其中包含了一些关键信息,如用户的身份标识和其他相关的个人信息。
-
Token的设计兼具安全性和易用性的特点
-
主要体现在以下方面:
-
安全性:
-
Token采用了加密算法进行生成和验证,使得其具有一定的安全性。
-
加密后的字符串中已携带了用户的身份信息,并且被加密处理,防止了明文传输和篡改。
-
-
隐私保护:
-
Token将个人信息等敏感数据存储在服务器端,而不是在前端或浏览器中。
-
这样可以降低用户信息泄露的风险。
-
前端只需要在每次请求时携带Token,而无需传递用户的具体身份信息,保护了用户的隐私。
-
-
前后端分离:
-
Token的特性非常契合前后端分离架构。
-
在传统的基于Session的身份验证中,服务器需要维护用户的会话状态,而在前后端分离中,服务器无需保存会话状态,而是通过验证Token的方式进行身份认证。
-
这样可以提高服务器的可扩展性和并发处理能力,减轻了服务器的负担。
-
-
易用性:
- Token的使用相对简单,前端在登录成功后会收到一个Token,并将其存储在客户端(如浏览器的Cookie或本地存储中)。
- 后续的请求中,只需要在请求头中带上Token即可完成身份验证和授权。
- 这种方式方便了前端的开发和维护,并且可以支持跨域访问。
-
-
-
总体而言
- Token作为一种身份验证和授权的机制,在前后端分离的架构中具有很好的适应性。
- 它既保证了安全性,又降低了服务器负担,同时提供了方便的接口访问方式。
- 然而,在设计和实现过程中,仍需考虑Token的生成算法、存储方式、过期时间等相关安全问题,以保证系统的整体安全性。
【四】JWT
JSON格式的Token字符串
-
JWT(JSON Web Token)是一种基于JSON格式的令牌字符串,用于在前后端分离的应用中进行身份验证和授权。
-
JWT由三部分组成:
- 头部(Header)
- 载荷(Payload)
- 签名(Signature)。
-
每一部分都使用Base64编码,通过点(.)进行分隔,形成一个完整的JWT字符串。
-
具体结构如下:
xxxxx.yyyyy.zzzzz
【1】头部(Header):
- 头部通常包含两部分信息,令牌的类型(typ)和使用的加密算法(alg)。
- 例如,在一个JWT令牌中,头部可能如下所示:
{
"typ": "JWT",
"alg": "HS256"
}
【2】载荷(Payload):
-
载荷是JWT的主要信息存放位置,可以包含一些自定义的声明(Claims),也可以使用一些预定义的声明。
-
常见的预定义声明有:
-
iss:令牌发行者(Issuer)
-
sub:令牌主题(Subject)
-
aud:令牌受众(Audience)
-
exp:令牌过期时间(Expiration Time)
-
iat:令牌的签发时间(Issued At)
-
nbf:令牌的生效时间(Not Before)
-
jti:令牌的唯一标识(JWT ID)
-
-
例如,一个包含用户ID和角色的JWT载荷可以如下所示:
{
"userId": "123456",
"role": "admin"
}
【3】签名(Signature):
- 为了保证JWT的真实性和完整性,在服务器端对头部和载荷进行签名生成签名信息。
- 签名需要使用一个密钥(秘钥),通常是一个只有服务器知道的字符串,用于验证令牌的合法性。
【4】校验
- 在客户端使用JWT时,首先会将头部、载荷和签名信息按照一定规则组装成一个完整的JWT字符串,并将其发送到服务器进行验证。
- 服务器会解析JWT,验证签名的正确性和有效期,以确定用户的身份和权限。
【5】总结
- JWT作为一种基于JSON格式的令牌字符串,适用于前后端分离架构中的身份验证和授权。
- 它具有的优点包括可扩展性、状态无关性和自包含性。
- 但需要注意的是,在使用JWT时需注意安全性,包括选择合适的加密算法、保护密钥的安全性以及防止信息泄露等。
【补充】使用Django实现token功能
使用Django实现token功能 - 中间件
- 在Django中实现Token功能可以使用中间件来处理请求和响应
- 以下是一个简单的实现示例:
# my_app/middleware.py
from django.http import HttpResponseForbidden
from django.conf import settings
class TokenMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 在请求处理之前执行的代码
if not self.is_valid_token(request):
return HttpResponseForbidden("Invalid token")
response = self.get_response(request)
# 在请求处理之后执行的代码
return response
def is_valid_token(self, request):
# 根据实际情况从请求中获取Token,通常可以从请求头或请求参数中获取
token = request.META.get('HTTP_AUTHORIZATION', '').split(' ')[1]
# 验证Token的逻辑,可根据自己的认证方式进行实现
# 例如,可以使用JWT库进行解析和验证
try:
# 对Token进行验证和解码
# 如果验证通过,返回True,否则返回False
decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
return True
except jwt.exceptions.DecodeError:
return False
- 要使用此中间件,需要在Django的配置文件中进行相应的设置:
# settings.py
MIDDLEWARE = [
# 其他中间件...
'my_app.middleware.TokenMiddleware',
]
- 在上述示例中
- TokenMiddleware是一个自定义的中间件类,它在每个请求到达和离开Django视图之前都会被调用。
- is_valid_token方法用于验证Token的有效性,可以根据实际需求进行修改。
- 如果Token无效或不存在,中间件返回一个
HttpResponseForbidden
并拒绝请求。
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17581824.html