python|web框架|增加BasicAuth认证

简介: python|web框架|增加BasicAuth认证

上一篇文章,我们已经为框架定义了【响应对象】,该框架不仅可以获取客户端上传的报文信息,还能生成一些简单信息,如自定义响应头等等。今天我们再次完善一下该框架,给框架增加权限验证的功能,给框架加上一个BasicAuth的方法。


本篇文章所依赖的环境为:

image.png


本次代码已经放到了gitee上:gitee.com/pdudo/golea…


什么是http BashAuth


在日常生活或者工作中,你是否见到过这样的页面呢?

image.png

当我们打开窗口,网页并不是里面加载出来的,而是弹出了一个输入框,让我们输入其用户名和密码,输入后待服务器验证通过后,才开始展现实际的网页内容。这个就是BashAuth了,全称为: Basic access authentication,也称基本认证。是一种极其简单http协议身份验证方式。BashAuth认证的方式是通过请求头来发送和校验的,而非我们熟知的cookietoken等。


还有一点需要注意,这里所展现的输入框,其实是浏览器底层拆解协议所支持的。




BasicAuth认证底层原理


BasicAuth使用的http协议进行身份验证的,所以会将身份信息携带在请求头中进行传输。


第一步: 用户在第一次进行浏览器请求页面的时候,不会携带认证信息,此时服务器接接收信息后,判断报文中请求头没有WWW-Authenticate,此时会返回客户端报文,其中需要将报文响应状态码为401,响应头新增一个keyWWW-


Authenticate,值为realm加上请求域,做法是为了避免和其他URL相冲突。所以响应核心报文为:

HTTP/1.0 401 Unauthorized
WWW-Authenticate: Basic realm="pdudo sites"

其中状态码为401代表客户端错误,指的是需要身份验证,WWW-Authenticate响应头的值为Basic realm="pdudo sites"Basic代表验证的模式,realm代表请求域,请求域是为了和其他URL相冲突。


第二步: 当浏览器接收到该报文后,会判断其状态码为401并且请求头中有keyWWW-Authenticate,此时便会弹出输入框,让用户输入信息以便服务器校验。

输入之后,不是直接发送给服务器,而是会根据服务器发送的验证模式进行校验,如basic,加入客户端发送的报文如下:

GET /index HTTP/1.1
HTTP_AUTHORIZATION: Basic cGR1ZG86anVlamlu

其中Get代表请求方式,/index表示请求路径,HTTP/1.1http的版本。请求头HTTP_AUTHORIZATION表示验证数据,Basic是验证方式,cGR1ZG86anVlamlu表示用户名:密码,只不过浏览器使用base64进行编码了而已。


第三步: 服务器在接收到报文后,发现有HTTP_AUTHORIZATION,则会使用base64解码,发现客户端上传的数据为pdudo:juejin,以:为分割,前者是用户名,后则是密码。当验证通过后,进行发送其他信息,若验证未通过,则重复第一步。



BasicAuth认证添加到框架中


我们已经知晓了BasicAuth认证的底层原理,所以可以开始修改我们的框架了,我们将其代码写到上一篇所述的response类中,代码如下:

def basicAuth(self):
    if "HTTP_AUTHORIZATION" not in self.response:
        return None,None,"HTTP_AUTHORIZATION request header not found"
    else:
        originalVal = self.response["HTTP_AUTHORIZATION"]
        types = originalVal.split(" ")[0]
        values = originalVal.split(" ")[1]
        if types == "Basic":
            userAndPasswd = base64.b64decode(values).decode()
            user = userAndPasswd.split(":")[0]
            passwd = userAndPasswd.split(":")[1]
            return user,passwd,None
        else:
            return None, None, "HTTP_AUTHORIZATION request error,unrecognized type: %s " %(types)




当客户端函数调用basicAuth时,服务器检查客户端http报文中,是否有HTTP_AUTHORIZATION,如果没有,则直接返回HTTP_AUTHORIZATION request header not found


若请求头有该key,则将其抓出来存储到originalVal中,它的值类似于: Basic cGR1ZG86anVlamlu,前者是认证类型,后者是加密后字符串,所以我们需要分开将其取出来,存到typesvalues中,再判断types是否是Basic,如果是我们使用base64进行解密,解密后的值类似于pdudo:juejin,以冒号(:)隔开,前者为用户名,后者为密码,所以我们需要将字符串按照:进行拆分,前者保存到user中,后者保存到passwd中,最后将其数据给函数。


那当第一步检查请求头没有HTTP_AUTHORIZATION或者用户名密码不对,应该如何返回呢? 这个需要用户在函数中进行调用即可,例如:

@myWeb.routes(path="/index",methods="all",regular=False)
def index(r):
    username, password , isok = r.basicAuth()
    if isok != None or username != "pdudo" or password != "juejin":
        r.set_headers("WWW-Authenticate","Basic realm="pdudo sites"")
        r.status_code(401)
        return
    return "123"

上述代码,使用我们自己编写的myWeb框架,定义了一个路由/index,其方法为Get或者Postregular=False则不使用正则路由,在函数中,通过r.basicAuth()来获取客户端上传的用户名密码,当用户名不等于pdudo或者密码不等于juejin或者解析失败的时候,会将响应状态码定义为401,并且设置响应头,keyWWW-Authenticate,值为Basic realm="pdudo sites"



框架功能测试


这里就不贴myWeb.py的代码了,太长了,大家可以去gitee上看,这里贴一下main.py代码:

image.png


为了方便,我将每次获取到的数据,都打印一下,方便待会查看数据。

执行代码后,打开浏览器输入http://pdudo.juejin.cn:8888/index,当弹出框后,我们第一个故意输错,第二次才输正确:

image.png

我们查看服务器日志,如下:

image.png



一共收到了3次,第一个输出后,并没有携带报文,被挡回来了,所以用户名和密码都为None,第二次则是密码输入不正确被挡回来了,第三次输入正确,成功得到数据123



总结


本篇文章,我们介绍了一个极其古老的认证方式: BashAuth, 它是通过请求头来发送数据和验证的。接着我们了解了一下其认证过程,其中最常用的是类型是Basic,它表示将数据进行base64编码后传输,注意是编码,不是加密。所以在使用该功能的时候,最好配合https使用,以便被抓包后破解。 最后将其添加到我们的web框架myWeb.py中。


相关文章
|
1天前
|
机器人 Shell 开发者
`roslibpy`是一个Python库,它允许非ROS(Robot Operating System)环境(如Web浏览器、移动应用等)与ROS环境进行交互。通过使用`roslibpy`,开发者可以编写Python代码来远程控制ROS节点,发布和订阅话题,以及调用服务。
`roslibpy`是一个Python库,它允许非ROS(Robot Operating System)环境(如Web浏览器、移动应用等)与ROS环境进行交互。通过使用`roslibpy`,开发者可以编写Python代码来远程控制ROS节点,发布和订阅话题,以及调用服务。
18 8
|
2天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
【7月更文挑战第13天】在Web开发中,AJAX和Fetch API是实现页面无刷新数据交换的关键。在Flask博客系统中,通过创建获取评论的GET路由,我们可以展示使用AJAX和Fetch API的前端实现。AJAX通过XMLHttpRequest发送请求,处理响应并在成功时更新DOM。Fetch API则使用Promise简化异步操作,代码更现代。这两个工具都能实现不刷新页面查看评论,Fetch API的语法更简洁,错误处理更直观。掌握这些技巧能提升Python Web项目的用户体验和开发效率。
15 7
|
2天前
|
XML 前端开发 API
惊艳全场的秘诀!AJAX、Fetch API与Python后端,打造令人惊叹的Web应用!
【7月更文挑战第13天】构建现代Web应用的关键在于提供无缝用户体验,这涉及AJAX和Fetch API的异步数据交换以及Python(如Flask)的后端支持。Fetch API以其基于Promise的简洁接口,改进了AJAX的复杂性。例如,一个Flask应用可提供用户数据,前端利用Fetch API在不刷新页面的情况下显示信息。这种结合提升了效率,减少了服务器负载,是现代Web开发的趋势。随着技术发展,预期将有更多工具优化这一过程。
10 3
|
1天前
|
前端开发 API 开发者
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
【7月更文挑战第14天】在Web开发中,AJAX和Fetch API扮演着关键角色,用于前后端异步通信。AJAX通过XMLHttpRequest实现页面局部更新,但回调模式和复杂API有一定局限。Fetch API作为现代替代,利用Promise简化异步处理,提供更丰富功能和错误处理。Python后端如Flask、Django支持这些交互,助力构建高性能应用。从AJAX到Fetch API的进步,结合Python,提升了开发效率和用户体验。
6 0
|
1天前
|
XML 前端开发 API
颠覆传统!AJAX、Fetch API与Python后端,开启Web开发新篇章!
【7月更文挑战第14天】Web开发中,AJAX作为异步通信先驱,与新兴的Fetch API一起革新交互体验。Fetch基于Promise,简化了请求处理。Python后端,如Flask,提供稳定支撑。这三者的融合,推动Web应用达到新高度,实现高效、实时交互。通过示例展示,我们看到从发送请求到更新UI的流畅过程,以及Python如何轻松返回JSON数据。这种组合揭示了现代Web开发的潜力和魅力。
7 0
|
1天前
|
安全 API 数据库
Django/Flask不只是框架,它们是你Web开发路上的超级英雄!
【7月更文挑战第14天】Django与Flask,Python Web开发的双雄。Django提供全面功能,如ORM、模板引擎,适合大型项目;Flask轻量灵活,适用于快速迭代的定制化应用。Django示例展示ORM简化数据库操作,Flask示例演示构建RESTful API的便捷。两者各有所长,为开发者创造无限可能。**
|
1天前
|
网络协议 安全 Python
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
5 0
|
1天前
|
Python
`cmd`模块是Python标准库中的一个模块,它提供了一个简单的框架来创建命令行解释器。
`cmd`模块是Python标准库中的一个模块,它提供了一个简单的框架来创建命令行解释器。
4 0
|
5天前
|
存储 JavaScript 前端开发
WEB三大主流框架之Angular
WEB三大主流框架之Angular
|
Go Docker 容器
gin web框架docker多阶段构建实战
自从知道有多阶段构建以后,就实战了一把,顺便记录下来,供参考
886 0