7. session和token

本文深入探讨了两种用户请求合法性验证方法:Session和Token。Session依赖于服务器存储和Cookie,适合小型应用,但存在性能和扩展性问题。Token机制则通过哈希算法确保数据完整性,提高性能,适用于大规模用户场景。文章详细阐述了两种机制的工作原理及其优缺点。
摘要由CSDN通过智能技术生成

操作系统: windows
IDE: Pycharm

现在已经根据接口文档,编写代码, 能够对前端发来的 Customer API请求进行处理了。并且也有了用户登录处理的代码。

但是前端发来的 Customer API 请求, 我们后端代码就直接处理了,也就是说如果在浏览器中,直接输入查询客户信息的url,就能直接访问到,并没有验证这个请求是不是已经登录的管理员发出的。这显然是不合理的。

这就 需要我们在 处理 Customer API 请求前, 判断发出该请求的用户是否登录了。
对于请求消息的合法性验证, 通常有两种方案: sessiontoken


session方案:

session就是会话的意思。

session方案的原理如下:
服务端在数据库中保存一张session表。 这张表记录了一次用户登录的相关信息。
具体记录什么信息, 不同的系统各有差异, 通常会记录该用户的 ID 、姓名 、登录名之类的。

Django在migrate之后自动创建的表里就有,名字是django_session
django_session
这里的session_key就是session的id,唯一,用来标记一个session,session_data就是session的数据,在数据库中是加密的。

通过这张表,服务端可以根据 session号(通常叫session ID) 查到 session 的信息数据。
在用户登录成功后, 服务端就在数据库session表中创建一条记录,记录这次会话。

也就是创建一个新的 sessionid 插入到该表中。同时也放入一些该session对应的数据到 记录的数据字段中,比如登录用户的信息。

然后在该登录请求的HTTP响应消息中的头字段 Set-Cookie 里填入 sessionid 数据。

例如:

Set-Cookie: sessionid=6qu1cuk8cxvtf4w9rjxeppexh2izy0hh

根据HTTP协议, 这个Set-Cookie字段的意思就是要求前端将其中的数据存入浏览器的cookie中。 并且随后访问该服务端的时候, 在HTTP请求消息中必须带上这些 cookie数据。

cookie通常就是存储在客户端浏览器的一些数据。 服务端可以通过HTTP响应消息要求浏览器存储 一些数据。以后每次访问同一个网站服务, 必须在HTTP请求中再带上 这些cookie里面的数据。

cookie数据由多个键值对组成, 比如:

sessionid=6qu1cuk8cxvtf4w9rjxeppexh2izy0hh
username=byhy
favorite=phone_laptop_watch

该用户的后续操作,触发的HTTP请求, 都会在请求头的Cookie字段带上前面说的sessionid 。

例如:

Cookie: sessionid=6qu1cuk8cxvtf4w9rjxeppexh2izy0hh

服务端接受到该请求后,只需要到session表中查看是否有该 sessionid 对应的记录,这样就可以判断这个请求是否是前面已经登录的用户发出的。
如果不是,就可以拒绝服务,重定向http请求到登录页面让用户登录。

使用session验证客户端请求:

Django 对session 的支持是缺省就有的,下面我们来看看如何加入对API请求的合法性验证。

处理登录的函数中,有如下箭头所指的一行代码:
在这里插入图片描述
这行代码的作用是,在登录认证后,将用户类型保存到session数据中, 也就是存入数据库的那张表django_session的会话数据(session_data)记录中。

Django框架会自动在HTTP响应消息头中,加入类似下面的 sessionid cookie:

 Set-Cookie: sessionid=xxxxxx

后续的HTTP请求就会携带这个sessionid。

我们处理 URL 以 /api/mgr 开头的API请求代码里面, 需要加上一个验证逻辑:

  1. 验证请求的cookie里面是否有sessionid
  2. 检查session表,看看是否存在session_key为该sessionid的一条记录,该记录的数据字典session_data里面是否包含了usertype为 mgr 的数据

前面实现的代码中, 这些请求都是在dispatcher入口函数处理的,就在这里进行验证。
注意request对象里面的session属性对应的就是session记录里面的数据。
该数据对象类似字典,所以检查是否有usertype类型为mgr的信息,就是这样写:

if request.session['usertype'] != 'mgr' 

mgr/customer.pydispatcher函数的开始加上这段代码块:

    # 根据session判断用户是否是登录的管理员用户
    # sataus=302 http的响应是302 重定向
    if 'usertype' not in request.session:
        return JsonResponse({
            'ret': 302,
            'msg': '未登录',
            'redirect': '/mgr/sign.html'},
            status=302)

    if request.session['usertype'] != 'mgr':
        return JsonResponse({
            'ret': 302,
            'msg': '用户非mgr类型',
            'redirect': '/mgr/sign.html'},
            status=302)

清理过浏览器的cookie之后,跳过登录直接访问127.0.0.1:8080/mgr/index.html
就会报302错误,这是因为没有登录,session中就不存在usertype这个属性了,这就实现了用户的校验。
在这里插入图片描述
在这里插入图片描述


token方案:

使用session机制验证用户请求的合法性的主要缺点有两个:

  1. 性能问题
    因为,验证请求是根据sessionid到数据库中查找session表的,而数据库操作是服务端常见的性能瓶颈,尤其是当用户量比较大的时候。

  2. 扩展性问题
    当系统用户特别多的时候,后端处理请求的服务端通常由多个,部署在多个节点上。 但是多个节点都要访问session表,这样就要求数据库服务能够被多个节点访问,不方便切分数据库以提高性能。

token机制可以比较好的解决这些问题。

token简单来说,就是包含了数据信息校验信息的数据包。

Session机制是把数据信息(比如session表)放到服务端,服务端数据是客户无法篡改的,从而保证验证的可靠性

token机制将数据信息直接传给客户端,客户每次请求再携带过来给服务端。服务端无需查找数据库,直接根据token里面的数据信息进行校验。

那么问题来了:客户数据直接发送给客户端,如果客户端篡改了数据, 比如把自己改为vip用户怎么办? 服务端怎么验证数据有没有被客户端篡改(术语叫完整性验证)呢?

token 机制的原理如下:
服务端配置一个密钥(secret key),该密钥是服务端私密保存的,不能外泄
在用户登录成功后, 服务端将用户的信息数据 + 密钥 一起进行一个哈希计算, 得到一个哈希值。

注意:哈希算法保证了, 哈希值只能根据同样的源数据得到。所以这个哈希值,就是用来校验数据是否被修改的,将用户数据信息和哈希值一起做成一个字节串 ,这个字节串就称之为 token

服务端返回给客户的HTTP响应中返回了这个token。 通常token是放在HTTP响应的头部中的。 具体哪个头部字段没有规定,开发者可以自行定义。该用户的后续操作,触发的HTTP API请求, 会在请求消息里面带上token 。

服务端接收到请求后,会根据数据信息 和密钥,使用哈希算法再次生成哈希值。

如果客户没有修改数据,服务端根据原来的数据+密钥得到的哈希值和保存在token中原来的哈希值一致,就校验通过。校验通过后,就确信了数据没有被修改,可以放心的使用token里面的数据 进行后续的业务逻辑处理了。

使用token,由于不需要服务端访问查找数据库,从而大大了提高了处理性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值