摄像头组件,支持novif和http协议
This commit is contained in:
109
Windows/CS/Framework4.0/Camera/tplink.md
Normal file
109
Windows/CS/Framework4.0/Camera/tplink.md
Normal file
@@ -0,0 +1,109 @@
|
||||
豆干 HTTP 获取图片
|
||||
1. 获取图片的过程
|
||||
获取图片的流程如下图所示:
|
||||
|
||||
|
||||
各个阶段对应的示例报文(使用 Wireshark 抓取):
|
||||
总共包含 4 个报文(192.168.1.130 为客户端,192.168.1.60 为设备端):
|
||||
|
||||
1) 客户端发送获取图片请求
|
||||
|
||||
2) 设备端返回需要鉴权报文(其中 WWW-Authenticate 那一行指定了需要使用什么方式鉴权及鉴权相关信息)
|
||||
|
||||
3) 客户端完成鉴权,并再次发送获取图片请求(其中Authorization 那一行即是客户端完成鉴权后的加密信息)
|
||||
|
||||
4) 设备端返回图片
|
||||
|
||||
2. Postman 示例
|
||||
2.1 发出获取图片请求,返回要求鉴权报文,从中获取鉴权所需信息
|
||||
|
||||
2.2 根据鉴权所需信息生成鉴权信息,添加到请求头的 Authorization 字段中,鉴权信息使用通用 HTTP 认证中的 Digest 模式生成,具体请参考下方 3.2 备注一节
|
||||
|
||||
|
||||
3. 代码示例
|
||||
3.1 Python 代码
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import requests
|
||||
from hashlib import md5
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
|
||||
IP = "192.168.1.60"
|
||||
SNAPSHOT_URI = "/snapshot.jpg"
|
||||
SNAPSHOT_URL = "http://" + IP + SNAPSHOT_URI
|
||||
USER = "admin"
|
||||
PASSWD = "tp123456"
|
||||
|
||||
s = requests.Session()
|
||||
res = s.get(SNAPSHOT_URL) # 尝试获取图片
|
||||
if res.status_code == 401: # 需要鉴权
|
||||
# 鉴权方式为 WWW-Authenticate Digest
|
||||
auth_info = res.headers["WWW-Authenticate"]
|
||||
token = auth_info.split('"')
|
||||
realm = token[1]
|
||||
nonce = token[3]
|
||||
|
||||
user_info = USER + ":" + realm + ":" + PASSWD
|
||||
method = "GET:" + SNAPSHOT_URI
|
||||
|
||||
response = md5(
|
||||
(
|
||||
md5(user_info.encode(encoding="utf-8")).hexdigest()
|
||||
+ ":"
|
||||
+ nonce
|
||||
+ ":"
|
||||
+ md5(method.encode(encoding="utf-8")).hexdigest()
|
||||
).encode(encoding="utf-8")
|
||||
).hexdigest()
|
||||
|
||||
authorization = (
|
||||
"Digest username=\""
|
||||
+ USER
|
||||
+ "\",realm=\""
|
||||
+ realm
|
||||
+ "\",nonce=\""
|
||||
+ nonce
|
||||
+ "\",uri=\""
|
||||
+ SNAPSHOT_URI
|
||||
+ "\",response=\""
|
||||
+ response
|
||||
+ "\""
|
||||
)
|
||||
s.headers["Authorization"] = authorization # 设置鉴权信息
|
||||
|
||||
res = s.get(SNAPSHOT_URL) # 再次获取图片
|
||||
# 保存图片到本地
|
||||
im = Image.open(BytesIO(res.content))
|
||||
im.save("snapshot.jpg")
|
||||
|
||||
3.2 备注
|
||||
鉴权使用的方法是通用 HTTP 认证中的 Digest 模式,详细信息可参考:
|
||||
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/WWW-Authenticate
|
||||
|
||||
针对我们的设备,要完成鉴权,需要从设备端返回的要求鉴权报文中提取 WWW-Authenticate 字段的 realm 和 nonce 的值(对下图而言,就是 TP-LINK IP-Camera 和 d48bbb82dfa9e1e543af852b466d5612):
|
||||
|
||||
然后根据上述两个值以及用户名(应为 admin)和密码来生成鉴权字段 Authorization,该字段由以下几个部分组成(其中绿色部分代表恒定不变的,蓝色部分代表从请求鉴权的报文中获取的,橙色部分代表需要实时计算的(下面将说明计算方法)。例如参考上图,<realm> 应为 TP-LINK IP-Camera,而 <nonce> 应为 d48bbb82dfa9e1e543af852b466d5612):
|
||||
Digest username=”admin”,”realm=”<realm>”,nonce=”<nonce>”,uri=”/snapshot.jpg”,response=”<response>”
|
||||
|
||||
|
||||
|
||||
response 的计算方法(MD5 表示 MD5 加密):
|
||||
response = MD5(MD5(<username>:<realm>:<password>):<nonce>:MD5(<request-method>:<url>))
|
||||
|
||||
例如,对于上述请求鉴权报文而言,有
|
||||
变量 值
|
||||
username admin
|
||||
realm TP-LINK IP-Camera
|
||||
password tp123456
|
||||
nonce d48bbb82dfa9e1e543af852b466d5612
|
||||
request-method GET
|
||||
url /snapshot.jpg
|
||||
所以最终有
|
||||
response
|
||||
=
|
||||
MD5(MD5(admin:TP-LINK IP-Camera:tp123456):d48bbb82dfa9e1e543af852b466d5612:MD5(GET:/snapshot.jpg))
|
||||
=
|
||||
8326b7d2f53557bdde755f9899673b6c
|
||||
|
||||
Reference in New Issue
Block a user