みなさん、こんにちは。API を通じて投稿を更新する際、Content-Type に application/json を使用することは可能でしょうか?ドキュメント では可能と書かれていますが、実際にはできないのではないか と思い始めています。
常に [\"BAD CSRF\"] というエラーが返され、その意味が全くわかりません。
もし multipart/form-data を使用する必要がある場合、PUT リクエスト(特に data の部分)をどのように構築すればよいか、ご教示いただけますでしょうか。
header = CaseInsensitiveDict()
header["Authorization"] = '{"api-key": "longapikey", "api-username": "myusername"}'
{
"post": {
"raw": "Cool post, but here's an updated to the post's body",
"edit_reason": "I changed this because I can."
}
}
resp = requests.put(url, headers=headers, data=data)
よろしくお願いいたします。
david
(David Taylor)
2021 年 8 月 10 日午前 10:12
2
Api-Key と Api-Username は、Authorization ヘッダーの中に含めるのではなく、それぞれ独立したヘッダーとして送信する必要があります。以下のようにすると、よりうまくいくはずです。
header = CaseInsensitiveDict()
header["Api-Key"] = 'longapikey'
header["Api-Username"] = 'myusername'
これは、あなたの前のトピックと同じ問題のようです。
You are right, that’s something the tool I am using to test the API is doing and it works and that’s a problem on itself apparently:
header1 = CaseInsensitiveDict()
header1["Authorization"] = '{"api-key": "longapikey", "api-username": "myusername"}'
header2 = {"api-key": "longapikey", "api-username": "myusername"}
r = requests.get(url, headers= HEADER)
When HEADER == header1, it works, when == header2, I get:
{"errors":["You are not permitted to view the requested resource. The API username…
「いいね!」 2
返信ありがとうございます、David。
とても奇妙なことに、あなたが示した方法でヘッダーをフォーマットすると、以下のエラーが表示されます:
{"errors":["You are not permitted to view the requested resource. The API username or key is invalid."],"error_type":"invalid_access"}
しかし、["Authorization"] を追加すると、正常に動作します。
これは単純な GET リクエストの場合の話ですが、PUT リクエストはまだうまくいきません。
ある操作で機能するヘッダーは、(キーがグローバルであることが前提ですが)すべての操作で機能するはずだと期待していました。そのため、現時点ではヘッダーについてはあまり心配していません。ただ、気にするべきでしょうか?
ありがとうございます!
blake
(Blake Erickson)
2021 年 8 月 10 日午後 6:18
4
GET リクエストが、Authorization ヘッダーの扱いを誤っているにもかかわらず動作しているなら、おそらく PUT リクエストに何か不正な部分があるのでしょう。GET リクエストはそもそも認証が不要なため動作しています。ヘッダーを渡しても、当方は Authorization ヘッダーを確認することすらありません。パブリックエンドポイントへの GET リクエストは、ヘッダーなしでも問題なく動作します。
「いいね!」 1
blake
(Blake Erickson)
2021 年 8 月 10 日午後 6:47
5
@pedroleaoc 認証付きリクエストの作成方法と、PUT/POST リクエストでリクエストデータを送信する方法を示す、小さな Python スクリプトのサンプルです。
# discourse-api-demo.py
import requests
from requests.structures import CaseInsensitiveDict
# ヘッダー不要なパブリック URL への基本的な GET リクエスト
url = "http://localhost:3000/posts/10.json"
resp = requests.get(url)
print(resp.status_code)
print(resp.content)
# 認証ヘッダーが必要なプライベートエンドポイントへの GET リクエスト
url = "http://localhost:3000/admin/users/list/active.json"
headers = {'Api-Username': 'system', 'Api-Key': '5c1c57915e2...'}
resp = requests.get(url, headers=headers)
print(resp.status_code)
print(resp.content)
# リクエストボディ付きの PUT リクエスト
url = "http://localhost:3000/posts/10.json"
data = { 'raw': "Cool post, but here's an updated to the post's body", 'edit_reason': "I changed this because I can." }
resp = requests.put(url, headers=headers, json=data)
print(resp.status_code)
print(resp.content)
Quickstart — Requests 2.33.1 documentation より
dict を自分でエンコードする代わりに、json パラメータ(バージョン 2.4.2 で追加)を直接使用して渡すこともできます。これにより自動的にエンコードされます:
url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, json=payload)
なお、data または files のいずれかが渡された場合、json パラメータは無視されます。
リクエストで json パラメータを使用すると、ヘッダー内の Content-Type が application/json に変更されます。
「いいね!」 1
ああ、そっか!GETリクエストすべてにAuthorizationが必要ってわけじゃないんだ!
そんな貴重なヒントをありがとう、調べてみるね。感謝!
リバースエンジニアリングですでにわかっていること:
api_key ではなく api-key
PUT リクエストには "content-type": "application/x-www-form-urlencoded" が必要
データはJSONではない(暗号化されているが、正しいエンコーディングがまだ見つからない)
blake
(Blake Erickson)
2021 年 8 月 10 日午後 6:51
7
この直前の私の投稿 をご覧ください。リクエストで data=data 形式の代わりに json=data を使用すると、Python の requests ライブラリが content-type を自動的に処理し、application/json に設定してくれます。これが使用するべき形式です。
「いいね!」 2
素晴らしい、これで投稿を編集できるようになりました!お手伝いいただきありがとうございます。
残るはもう一つの問題です。現在使用しているキーは global です。write と read の権限のみを持つキーで試すと、「指定されたリソースを表示する権限がありません。API ユーザー名またはキーが無効です」というエラーになります。GUI を通じて投稿を編集すると、実際に投稿を編集する posts/post_id.json へのリクエストとは別に、トピックの URL への PUT リクエストが発生しているようですが、これは制限付きの API キーでは再現できず、global キーでのみ発生します。しかし、なぜか、この GUI 側で発生する余分な PUT リクエストがなくても、API を通じて投稿を編集できない理由がわかりません。
追記:技術的には、私の API キーは PUT リクエストが向かっている /t/:slug/:topic_id をカバーしています。
blake
(Blake Erickson)
2021 年 8 月 10 日午後 7:35
9
API キーに「投稿の編集」スコープが選択されていますか?
いいえ!そのオプションは私にはありません!確認してみます。またもやご助力いただき、ありがとうございます。
「いいね!」 1
system
(system)
クローズされました:
2021 年 9 月 9 日午後 9:24
11
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.