使用Honeywell API控制温控器OAuth2授权问题:授权码流vs客户端凭证流
问题分析与解决方案
核心原因:两种OAuth2授权流的本质差异
你遇到的问题确实是授权码流和客户端凭证流的区别导致的:
- 授权码流生成的Token:绑定了你的个人用户账号,API能识别到要访问的是你名下的温控器设备。
- 客户端凭证流生成的Token:仅代表你的应用程序本身的权限,没有关联任何具体用户,霍尼韦尔API无法确定要访问哪个用户的设备,因此返回
Unauthorized。
关键解决步骤:添加UserRefID标识用户
你提到的UserRefID就是用户唯一标识,需要在API请求中带上它,让API明确要访问的用户设备。
1. 获取你的UserRefID
用之前能正常工作的授权码流Token,调用霍尼韦尔用户信息接口获取:
def get_user_ref_id(valid_bearer_token): url = "https://api.honeywell.com/v2/users/me" params = {"apikey": client_id} headers = { "Authorization": f"Bearer {valid_bearer_token}", "Accept": "*/*" } response = requests.get(url, params=params, headers=headers) return response.json()['userRef'] # 此处的userRef即为UserRefID
传入你从开发者网站复制的有效Token,就能拿到你的UserRefID。
2. 修改API请求,添加UserRefID
在gettemp函数的请求头中加入UserRefID字段:
headers = { "Accept": "*/*", "Accept-Encoding": "gzip", "Accept-Language": "en-US", "Authorization": f"Bearer {bearer}", "UserRefID": "你的UserRefID", # 新增该行 "DNT": "1", "Host": "api.honeywell.com", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }
3. 补充:完善客户端凭证流的权限范围
你获取的客户端凭证流Token返回scope为空,这也可能导致权限不足。尝试在获取Token时添加对应权限的scope参数:
data = { 'grant_type': 'client_credentials', 'scope': 'thermostats_read thermostats_write' # 根据需求添加权限 }
具体可用scope需参考霍尼韦尔开发者文档,确保你的应用已被授予对应权限。
验证修改
调整后重新调用gettemp函数,即可正常获取温控器数据。
内容的提问来源于stack exchange,提问作者Greg Wyatt
相关产品推荐
相关产品推荐

