Bash转Python脚本后API调用出现403认证错误求助
API认证排查:Bash脚本正常但Python脚本返回403错误
我将一段可正常调用API的Bash脚本转换为Python脚本后,Python版本调用API返回<Response [403]>认证错误,但原Bash脚本可正常认证并获取数据。以下是原Bash脚本、出错的Python脚本,以及之前可正常运行的Python脚本(仅API_HOST和PRODUCT路径不同),请帮忙排查转换过程中的问题:
原Bash脚本
AUTH_HOST=xxxx AUTH_URL="https://${AUTH_HOST}/as/token.oauth2" USERID='api_someuser' PASSWORD='something' ESCAPED_PASSWORD='something_escaped' API_HOST="refdata.api.cmegroup.com" PRODUCTS="https://${API_HOST}/refdata/v3/products" INSTRUMENTS="https://${API_HOST}/refdata/v3/instruments" resp=$(curl --silent "${AUTH_URL}" --request POST \ -H "Host: ${AUTH_HOST}" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=${USERID}&client_secret=${ESCAPED_PASSWORD}") TOKEN=$(echo "$resp" | jq --raw-output '.access_token') page=$(curl --silent "${PRODUCTS}" --request GET \ -H "Host: ${API_HOST}" \ -H "Authorization: Bearer ${TOKEN}")
出错的Python脚本
import json import requests AUTH_HOST=xxxx AUTH_URL=f"https://{AUTH_HOST}/as/token.oauth2" USERID='api_someuser' PASSWORD='something' ESCAPED_PASSWORD='something_escaped' API_HOST="refdata.api.cmegroup.com" PRODUCTS=f"https://{API_HOST}/refdata/v3/products" INSTRUMENTS=f"https://{API_HOST}/refdata/v3/instruments" headers = {"Host": AUTH_HOST, "Content-Type": "application/x-www-form-urlencoded",} data = { "grant_type":"client_credentials", "client_id": USERID, "client_secret":PASSWORD } ### send post request resp = requests.post(AUTH_URL, data=data, headers=headers) token = resp.json()['access_token'] header_for_page = {"Host": API_HOST, "Authorization": f"Bearer {token}"} page = requests.get(PRODUCTS, headers = header_for_page) breakpoint()
之前可正常运行的Python脚本
import json import requests USERID='api_someuser' PASSWORD='something' ESCAPED_PASSWORD='something_escaped' AUTH_HOST="auth.cmegroup.com" AUTH_URL="https://auth.cmegroup.com/as/token.oauth2" headers = {"Host": AUTH_HOST, "Content-Type": "application/x-www-form-urlencoded",} data = { "grant_type":"client_credentials", "client_id": USERID, "client_secret":PASSWORD } ### send post request resp = requests.post(AUTH_URL, data=data, headers=headers) token = resp.json()['access_token'] API_HOST="api.refdata.cmegroup.com" PRODUCTS=f"https://{API_HOST}/v2/products" header_for_page = {"Host": API_HOST, "Authorization": f"Bearer {token}"} page = requests.get(PRODUCTS, headers = header_for_page) breakpoint()
问题排查与修复
核心错误:client_secret参数不匹配
原Bash脚本请求认证接口时,使用的是转义后的密码ESCAPED_PASSWORD,但出错的Python脚本误用了未转义的PASSWORD,这直接导致认证失败返回403。之前正常运行的Python脚本能成功,是因为对应的API环境允许使用未转义的密码,而当前新API要求必须用转义后的版本。修复步骤
修改出错的Python脚本中的data字典,将client_secret的值替换为ESCAPED_PASSWORD:data = { "grant_type":"client_credentials", "client_id": USERID, "client_secret": ESCAPED_PASSWORD # 替换为转义后的密码 }额外优化建议
requests库会自动根据请求URL生成正确的Host头,手动设置可能因拼写或格式问题导致异常,建议去掉脚本中手动添加的Host头,简化代码。
内容的提问来源于stack exchange,提问作者kfsopdf
相关产品推荐
相关产品推荐

