Unicode usernames

Currently discourse unicode usernames does not work with the api

Is it possible to fix this bug?

I just tried this and it works for me:

○ → 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"
}

Can you demonstrate how it fails for you?

2 Likes

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

  1. Test interface

https://docs.discourse.org/#tag/Posts/operation/listPosts

2.web address

https://xxxxxxxx/posts.json

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.

What are you using? The error looks like python? This is supported by requests but possibly not by the libraries you’re using.

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'}

Try calling .encode() to explicitly convert the header value to bytes… though admittedly since not everything is 8-bit clean I do agree this suggestion:

is reasonable.

3 Likes

Search the forums Older versions of the api can be used with Query

Newer versions of the api don’t work Query

Is it compatible with Query Fix this issue

例如:

https://www.xxx.com/posts.json?api_key=714552c6148e1617aeab526d0606184b94a80ec048fc09894ff1a72b740c5f19&api_username=system

Hopefully, this will be resolved.

It won’t, you now need to pass the API parameters as headers instead of query parameters. That won’t change.

2 Likes

But the header can not pass non-ASCII characters, I want to pass the Chinese user name

It can, as proven by @supermathie above:

cURL

Python:

2 Likes

In fact, it does not work, I have tried, because the header can not contain non-ASCII characters, you need to do an encoding conversion, but after encoding the characters, it will prompt the user name does not exist, because in the discourse on the receiving end did not restore!!

The headers need to be encoded as UTF-8, not with URI encoding.

2 Likes
  1. 1: the header cannot contain Chinese characters
  2. 2: utf8 refers to the content in the post, not the header
  3. 3: Discourse is not decoded by UrlEncode, it will show that the username does not exist.

The following test data is provided

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

Thank you! Michael Brown

1 Like

You’ll want to rotate that API key immediately @zengyunsi, consider it leaked.

… though I can confirm it does work when you encode the headers with 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
2 Likes

Is this the case and can you provide an example, thanks!

Content-Type: Application/json; charset=utf-8
Accept: Application/json; charset=utf-8
Api-Key: f9c13aafa9b21baf778161bff66a62533ba650b6e4542e3e9788e98c55ded869
Api-Username: \xe9\xa3\x8e\xe4\xb9\x8b\xe6\x97\x85\xe4\xba\xba

Always prompt
You are not permitted to view the requested resource. The API username or key is invalid

I can confirmed that below example would work:

$ 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":[]}

And without api-* header:

$ 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 example:

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]>

Seems your api-username does not encode appropriately

>>> '风之旅人'.encode()
b'\xe9\xa3\x8e\xe4\xb9\x8b\xe6\x97\x85\xe4\xba\xba'
1 Like

Thank you all, I’m going to try, if you can use the Chinese user name to call the api operation is more convenient, thank you!


This is a bit weird and I can’t use the api normally either

It much likely an issue with the API key scope.

:sweat_smile:我试了下好像也不行 不过我不会Python
一样的提示··

Does the same call with an ASCII username work?

(I’m guessing no and that’s what you mean by “I can’t use the API normally”)

If so, does the website have another proxy in front of it or is it using the standard install?

Yeah, this call encoded it as a escaped representation of the UTF-8 byte sequence, rather than the bytes themselves.