Python request访问401错误与权限验证
最近,在使用Python requests接口访问开发的过程中,遇到401错误,跟踪原因是 Unauthorized ,这个错误通常意味着我在尝试访问某个资源时侯,没有提供正确的身份验证信息,或者你的身份验证信息已经过期。
在如此场景中,接口需要先进行登录操作以获取 AccessToken,然后使用这个 Token 来验证请求,同时,还可能需要签名等确保数据安全。如下图所示是我按此场景整理出来的访问处理过程程。

1. 带有身份验证的 Python 请求
Token是用于身份验证,通常通过 HTTP 请求头传递。在 requests 中,通常会直接处理 token的。
1.1. 发送登录请求以获取AccessToken
首先,你需要发送一个登录请求到服务器的登录端点,通常是一个POST请求,包含用户名和密码。服务器验证这些信息后,如果成功,会返回一个AccessToken。
python
import requests
# 登录URL
login_url = 'https://api.example.com/login'
# 登录数据,通常是用户名和密码
login_payload = {
'username': 'your_username',
'password': 'your_password'
}
# 发送登录请求
login_response= requests.post(login_url, json=login_payload)
# 检查请求是否成功
if response.status_code == 200:
# 从响应中获取AccessToken
access_token = login_response.json()['Data'].get('AccessToken')
# 如果有RefreshToken,也一并保存
refresh_token = login_response.json()['Data'].get('RefreshToken')
else:
print('登录失败:', login_response.text)
# 处理错误
1.2. 使用AccessToken发送请求
得到AccessToken,就可以在请求头中设置Authorization字段,并使用该Token来访问需要身份验证的资源。
# 资源URL
resource_url = 'https://api.example.com/protected_resource'
# 设置请求头,包含AccessToken
headers = {
'Authorization': 'Bearer ' + access_token
}
# 发送请求
response = requests.get(resource_url, headers=headers)
# 检查请求是否成功
if response.status_code == 200:
# 处理成功的响应
print('请求成功:', response.json())
else:
# 处理失败的响应,可能是Token过期或其他错误
print('请求失败:', response.text)
1.3. Token刷新
如果AccessToken有有效期,并且快到期了,你需要使用RefreshToken来获取一个新的AccessToken。这个过程通常也是一个POST请求,发送到服务器的Token刷新端点。
# Token刷新URL
refresh_url = 'https://api.example.com/refresh_token'
# 设置请求头,包含RefreshToken
refresh_headers = {
'Authorization': 'Bearer ' + refresh_token
}
# 发送Token刷新请求
refresh_response = requests.post(refresh_url, headers=refresh_headers)
# 检查请求是否成功
if refresh_response.status_code == 200:
# 从响应中获取新的AccessToken
new_access_token = refresh_response.json().get('access_token')
# 更新Token
access_token = new_access_token
else:
print('Token刷新失败:', refresh_response.text)
# 处理错误
2. 网络数据传输安全——对接口的数据进行MD5签名验证
我们在调用数据接口时,传输数据(或命令)做为一个文件,该文件使用MD5校验,那么在发送数据/文件的同时会再发一个存有校验码的文件,我们拿到该文件后做MD5运算,得到的计算结果与发送的校验码相比较,如果一致则认为发送的数据/文件没有出错,否则认为数据/文件出错需要重新发送。
要使用Python进行MD5加密,可以使用Python标准库中的hashlib模块。例如:
import hashlib
string = "Hello, World!" # 要进行加密的字符串
hash_object = hashlib.md5(string.encode()) # 将字符串编码并进行 MD5 加密
hash_hex = hash_object.hexdigest() # 获取加密后的十六进制字符串
print(hash_hex) # 输出加密后的字符串
3. 实际应用案例
如上图所示,首先,使用登录接口API,获取Token;接着构造接口请求header,放入应用id、Token;再构造传输数据,并形成MD5验证密文;再把MD5验证密文做为签名放入header;最后,调用目标接口。实际应用案例如下(部分内容省略):
import requests, json
import datetime
def test():
param = {
"Id":"",
"CreateTime":"2024-02-17 08:44:35",
"AlarmValue":None,
}
nowdate = datetime.datetime.now().strftime('%Y-%m-%d') # 当前日期
import uuid
# 登录
login_headers = {'Content-Type':'application/json'}
login_data = json.dumps(login_param)
try:
login_response = requests.post(cf.login_url, data=login_data, headers=login_headers, timeout=2)
# 检查登录是否成功
if login_response.status_code == 200:
print("登录成功")
for vid in pveqid:
guid = str(uuid.uuid1())
dd = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 提交数据
#headers = {'Content-Type':'application/json'}
param['CreateTime'] = dd
param['AlarmValue'] = guid
data_json = json.dumps(param)
sign = login_param['appId'] + dd + guid + str(data_json) + login_param['appSecret']
import hashlib
hash_object = hashlib.md5(sign.encode()) # 将字符串编码并进行 MD5 加密
hash_hex = hash_object.hexdigest() # 获取加密后的十六进制字符串
headers = {
'Authorization': 'Bearer ' + login_response.json()['Data']['AccessToken'],
'Content-Type': 'application/json',
'appId': login_param['appId'],
'appSecret': login_param['appSecret'],
'time': dd,
'guid': guid,
'sign': hash_hex
}
try:
ret = requests.post(cf.alarmurl, data= data_json, headers=headers, timeout=2) # timeout超时2秒
if ret.status_code == 200:
#ret_data = json.loads(ret.text)
ret_data = ret.json()
else:
pass
except:
pass
else:
# 登录失败
pass
except:
pass
if __name__ == '__main__':
test()
参考:
18.程序员. python使用MD5. CSDN博客. 2023.05