目前 discourse 的 unicode 用户名无法与 API 一起使用
可以修复此错误吗?
我刚试了一下,对我来说是有效的:
○ → curl -s -L -H 'api-key: «redacted»' -H 'api-username: doesnotexist' https://try.discourse.org/u/运思/notifications.json
{"errors":["You are not permitted to view the requested resource. The API username or key is invalid."],"error_type":"invalid_access"}
○ → curl -s -L -H 'api-key: «redacted»' -H 'api-username: 运思' https://try.discourse.org/u/运思/notifications.json | jq '.users[0]'
{
"id": 41,
"username": "运思",
"name": "Michael Brown",
"avatar_template": "/user_avatar/try.discourse.org/运思/{size}/208_2.png",
"trust_level": 1,
"assign_icon": "user-plus",
"assign_path": "/u/运思/activity/assigned"
}
你能演示一下它对你来说是如何失败的吗?
Thank you, Michael Brown.
I have tested it and if I test it in the browser it is ok, but in the programming software it is not ok, because the rule is that only ascii can be used to transfer this protocol.
Reason for the error:
TypeError: Invalid character in header content [“Api-Username”]
Please refer to the log, it is recommended to add ut8 encoding or decoding once for matching
2.web address
Accept:application/json
api-key:f9c13aafa9b21baf778161bff66a62533ba650b6e4542e3e9788e98c55ded869
Api-Username:system
Test results:
OK
Accept:application/json
api-key:f9c13aafa9b21baf778161bff66a62533ba650b6e4542e3e9788e98c55ded869
Api-Username:风之旅人
{“status”:500,“error”:“Internal Server Error”}
Accept:application/json
api-key:f9c13aafa9b21baf778161bff66a62533ba650b6e4542e3e9788e98c55ded869
Api-Username:%E8%BF%90%E6%80%9D
You are not permitted to view the requested resource. The API username or key is invalid
Reason for error:
The use of Chinese in the header is invalid, it needs to be encoded by encodeURI() in order to be transmitted to the server, but the server needs to decode decodeURI() in order to recognize it.
Suggest to add a judgment, if not found, try to decodeURI, match the username.
您在使用什么?这个错误看起来像 Python?这得到了 requests 的支持,但可能不是您正在使用的库的支持。
In [1]: import requests
In [2]: api_key = '«redacted»'
In [3]: r = requests.get('https://try.discourse.org/u/运思/notifications.json', headers = {
'api-key': api_key,
'api-username': '运思'.encode()
})
In [4]: r.status_code
Out[4]: 200
In [5]: r.json()['users'][0]
Out[5]:
{'id': 41,
'username': '运思',
'name': 'Michael Brown',
'avatar_template': '/user_avatar/try.discourse.org/运思/{size}/208_2.png',
'trust_level': 1,
'assign_icon': 'user-plus',
'assign_path': '/u/运思/activity/assigned'}
尝试调用 .encode() 来显式地将标头值转换为 bytes……尽管不可否认,由于并非所有内容都是 8 位干净的,我确实同意这个建议:
是合理的。
搜索论坛 旧版 API 可与 Query 一起使用
新版 API 不支持 Query
是否与 Query 兼容? 修复此问题
例如:
https://www.xxx.com/posts.json?api_key=714552c6148e1617aeab526d0606184b94a80ec048fc09894ff1a72b740c5f19&api_username=system
希望这个问题能得到解决。
不会的,你现在需要将 API 参数作为标头传递,而不是作为查询参数。这一点不会改变。
But the header can not pass non-ASCII characters, I want to pass the Chinese user name
事实上,它并不能工作,我已经尝试过了,因为标头不能包含非 ASCII 字符,您需要进行编码转换,但在编码字符后,它会提示用户名不存在,因为在接收端的 discourse 中没有恢复!!
标头需要编码为 UTF-8,而不是使用 URI 编码。
提供如下测试数据
https://www.baowei.ink/posts.json
{
"title": "标题标题标题标题标题",
"raw": "标题标题标题标题标题标题标题标题标题标题",
"category": 10,
}
Pass
Content-Type: application/json; charset=UTF-8
Api-Key: «redacted»
Api-Username: system
Fail
Content-Type: application/json; charset=UTF-8
Api-Key: «redacted»
Api-Username: 风之旅人
Content-Type: application/json; charset=UTF-8
Api-Key: «redacted»
Api-Username: %E9%A3%8E%E4%B9%8B%E6%97%85%E4%BA%BA
谢谢!Michael Brown
您应该立即轮换该 API 密钥 @zengyunsi,请将其视为已泄露。
……不过我可以确认,当您使用 UTF-8 对标头进行编码时,它确实有效:
In [1]: import requests
In [2]: api_key = '«redacted»'
In [3]: r = requests.get('https://www.baowei.ink/posts.json', headers={'api-key': api_key, 'api-username': '风之旅人'.encode()})
In [4]: r.status_code
Out[4]: 200
In [5]: len(r.json()['latest_posts'])
Out[5]: 19
这是这种情况吗?你能举个例子吗?谢谢!
Content-Type: Application/json; charset=utf-8
Accept: Application/json; charset=utf-8
Api-Key: f9c13aafa9b21baf778161bff66a62533ba650b6e4542e3e9788e98c55ded869
Api-Username: 风之旅人
始终提示
您无权查看所请求的资源。API 用户名或密钥无效
我可以确认以下示例将正常工作:
$ curl -s -L \
-H 'api-key: 60834ccb8eda28cf17bab8efbbb2fbf874eb8b5a75ff17ddbd2346eb292881a0' \
-H 'api-username: 测试用户' \
http://localhost:4200/u/%E6%B5%8B%E8%AF%95%E7%94%A8%E6%88%B7/emails.json
{"email":"discobot_email","secondary_emails":[],"unconfirmed_emails":[],"associated_accounts":[]}
并且在没有 api-* 标头的情况下:
$ curl -s -L \
http://localhost:4200/u/%E6%B5%8B%E8%AF%95%E7%94%A8%E6%88%B7/emails.json
{"errors":["You need to be logged in to do that."],"error_type":"not_logged_in"}
Python requests 示例:
import requests
api_key = '60834ccb8eda28cf17bab8efbbb2fbf874eb8b5a75ff17ddbd2346eb292881a0'
api_username = '测试用户'
api_endpoint = 'http://localhost:4200/u/%E6%B5%8B%E8%AF%95%E7%94%A8%E6%88%B7/emails.json'
r = requests.get(api_endpoint, headers={
'api-key': api_key, 'api-username': api_username.encode()})
print(r)
<Response [200]>
看起来你的 api-username 没有正确编码
>>> '风之旅人'.encode()
b'\xe9\xa3\x8e\xe4\xb9\x8b\xe6\x97\x85\xe4\xba\xba'
谢谢大家,我来试试,如果能用中文用户名调用api操作就更方便了,谢谢!
这很可能是 API 密钥范围的问题。
我试了下好像也不行 不过我不会Python
一样的提示··
使用 ASCII 用户名的相同调用是否有效?
(我猜不行,这就是你说的“我无法正常使用 API”的意思)
如果有效,该网站是在其前面使用了另一个代理,还是在使用标准安装?
是的,这个调用将其编码为 UTF-8 字节序列的转义表示形式,而不是字节本身。