Python Web开发(九):session|token 验证客户端请求

简介: Python Web开发(九):session|token 验证客户端请求

网络异常,图片无法展示
|

前言: 📢📢📢 🏅🏅🏅作者简介:是Dream呀,华为云享专家、年度博客之星、CSDN原力计划作者、Python领域优质创作者,专注分享Python领域原创系列文章。

💕 入门须知:这片乐园从不缺乏天才,努力才是你的最终入场券!🚀🚀🚀 💓最后,愿我们都能在看不到的地方闪闪发光,一起加油进步🍺🍺🍺

前面我们已经根据接口文档,编写代码, 对前端发来的 Customer API请求进行处理了。 并且我们也编写了 用户登录处理的代码。不知道大家有没有发现一个问题? 前端发来的 Customer API 请求, 我们后端代码就直接处理了, 并没有验证 这个请求是不是已经登录的管理员发出的。 如果是这样,客户端可以不需要登录,直接访问 登录后的主页, 我们编写的登录处理代码又 有什么用呢? 这就 需要我们在 处理 Customer API 请求前, 判断发出该请求的用户是否登录了。

对于请求消息的合法性验证, 通常有两种方案: sessiontoken

一、session方案

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

1.1 session id

Django 中 该表 名字就叫 django_session, 如下所示。

网络异常,图片无法展示
|
大家可以发现 session id (表中的session key)通常就是 一串字符串 用来标记一个session的。 而 session对应的数据在这里是加密的。 通过这张表,服务端 可以根据 session号(通常叫 session ID) 查到 session 的信息数据。 作用: 1.在用户登录成功后, 服务端就在数据库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

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

Cookie: sessionid=6qu1cuk8cxvtf4w9rjxeppexh2izy0hh

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

1.2 实际操作

首先我们启动服务器:

网络异常,图片无法展示
|
然后输入我们的网址: http://127.0.0.1:8080/mgr/sign.html,进入登录页面:
网络异常,图片无法展示
|

二、token机制

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

  1. 性能问题 因为,验证请求是根据sessionid 到数据库中查找session表的,而数据库操作是服务端常见的性能瓶颈,尤其是当用户量比较大的时候。
  2. 扩展性问题 当系统用户特别多的时候,后端处理请求的服务端通常由多个,部署在多个节点上。 但是多个节点都要访问session表,这样就要求数据库服务能够被多个节点访问,不方便切分数据库以提高性能。

最近比较流行的一种token机制可以比较好的解决这些问题。

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

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

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

那么问题来了:客户数据直接发送给客户端,如果 客户端篡改了数据, 比如把自己改为 vip用户怎么办? 服务端怎么验证数据有没有被客户端篡改(术语叫完整性验证)呢? token 机制的原理如下:1. 服务端配置一个密钥(secret key),该密钥是服务端私密保存的,不能外泄

2. 在用户登录成功后, 服务端将 用户的信息数据 + 密钥 一起进行一个哈希计算, 得到一个哈希值。 注意:哈希算法保证了, 哈希值只能根据 同样的 源数据得到。如果谁修改了用户信息, 除非他知道密钥,再次使用哈希算法才能得到 正确的新的 哈希值。所以这个哈希值,就是用来校验数据是否被修改的.

然后将 用户数据信息 和 哈希值 一起 做成一个字节串 ,这个字节串就称之为 token 。 大家可以发现 token 里面 包含了用户数据信息 和 用于校验完整性的哈希值。 然后,服务端返回给客户的HTTP响应中 返回了这个token。 通常token是放在HTTP响应的头部中的。 具体哪个头部字段没有规定,开发者可以自行定义。

3. 该用户的后续操作,触发的HTTP API请求, 会在请求消息里面 带上 token 。 具体在请求消息的什么地方 存放 token, 由开发者自己定义,通常也存放在http 请求 的头部中。

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

  • 如果客户修改了数据信息, 因为他不知道密钥,没法得到正确的新的哈希值,那么 服务端根据 篡改后的数据+密钥 得到的新 哈希值一定和 保存在token中的老哈希值 不同。就知道数据被修改了。
  • 如果客户没有修改数据,服务端 根据 原来的数据+密钥 得到的哈希值 和保存在token中原来的哈希值一致,就校验通过。

校验通过后,就确信了数据没有被修改,可以放心的使用token里面的数据 进行后续的业务逻辑处理了。

上述处理中,由于不需要服务端访问查找数据库,从而大大了提高了处理性能

三、使用session验证客户端请求

Django 对session 的支持是 缺省就有的,下面我们来看看如何加入对API请求的合法性验证。大家是否注意到,前面我们处理登录的函数中 有如下箭头所指的 一行代码:

网络异常,图片无法展示
|
这行代码的作用 就是在登录认证后,将 用户类型保存到session数据中, 也就是存入前面数据库的那张图的 会话数据记录中。 Django 框架 会自动在 HTTP 响应消息头中 加入 类似下面的 sessionid cookie

Set-Cookie: sessionid=????????

后续的HTTP请求就会携带这个session id, 我们处理 URL 以 /api/mgr 开头的 API 请求 代码里面, 需要 加上一个验证逻辑。 验证请求的cookie里面是否有sessionid,并且检查session表,看看是否存在session_key为该sessionid 的一条记录,该记录的数据字典里面是否 包含了 usertype 为 mgr 的 数据。 前面实现的代码中, 这些请求都是在dispatcher入口函数处理的,我们就只需在该dispatch中进行验证。 修改 mgr/customer.pydispatcher 函数:

网络异常,图片无法展示
|

在前面加上如下代码:

# 根据session判断用户是否是登录的管理员用户
    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)

网络异常,图片无法展示
|
注意request对象里面的session属性对应的就是 session记录里面的 数据。 该数据对象类似字典,所以检查是否有usertype类型为mgr的信息,就是这样写:

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

网络异常,图片无法展示
|
网络异常,图片无法展示
|
⬇️⬇️ ⬇️ 商务合作|交流学习|粉丝福利|Python全套资料⬇️ ⬇️ ⬇️ 欢迎联系~

目录
相关文章
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
101 3
|
18天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
107 45
|
24天前
|
数据采集 前端开发 算法
Python Requests 的高级使用技巧:应对复杂 HTTP 请求场景
本文介绍了如何使用 Python 的 `requests` 库应对复杂的 HTTP 请求场景,包括 Spider Trap(蜘蛛陷阱)、SESSION 访问限制和请求频率限制。通过代理、CSS 类链接数控制、多账号切换和限流算法等技术手段,提高爬虫的稳定性和效率,增强在反爬虫环境中的生存能力。文中提供了详细的代码示例,帮助读者掌握这些高级用法。
Python Requests 的高级使用技巧:应对复杂 HTTP 请求场景
|
7天前
|
JSON API 数据格式
Python中获取HTTP请求响应体的详解
本文介绍了如何使用Python的`requests`和`urllib`库发送HTTP请求并处理响应体。`requests`库简化了HTTP请求过程,适合快速开发;`urllib`库则更为底层,适用于性能要求较高的场景。文章详细演示了发送GET请求、处理JSON响应等常见操作。
|
13天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
29 1
|
16天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
1月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
137 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
1月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
147 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
19天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
31 2
|
1月前
|
SQL 关系型数据库 数据库
优化Web开发流程:Python ORM的优势与实现细节
【10月更文挑战第4天】在Web开发中,数据库操作至关重要,但直接编写SQL语句既繁琐又易错。对象关系映射(ORM)技术应运而生,让开发者以面向对象的方式操作数据库,显著提升了开发效率和代码可维护性。本文探讨Python ORM的优势及其实现细节,并通过Django ORM的示例展示其应用。ORM提供高级抽象层,简化数据库操作,提高代码可读性,并支持多种数据库后端,防止SQL注入。Django内置强大的ORM系统,通过定义模型、生成数据库表、插入和查询数据等步骤,展示了如何利用ORM简化复杂的数据库操作。
59 6