ما هو الـ `content-type` الصحيح عند تعديل المشاركات؟

مرحبًا أيها الأصدقاء، هل يمكنني استخدام application/json كـ Content-Type عند تحديث منشور عبر واجهة برمجة التطبيقات؟ تشير التوثيق إلى أن ذلك ممكن، لكنني بدأت أظن أنني لا أستطيع ذلك..

أحصل باستمرار على رسالة [\"BAD CSRF\"] ولا أدري ما تعنيه.


إذا كان علي استخدام multipart/form-data، فهل لديكم أي تلميحات حول كيفية بناء طلب الـ PUT؟ خاصةً الجزء الخاص بـ data.

header = CaseInsensitiveDict()
header["Authorization"] = '{"api-key": "longapikey", "api-username": "myusername"}'
{
  "post": {
      "raw": "منشور رائع، ولكن إليك تحديثًا لنص المنشور",
      "edit_reason": "قمت بتغيير هذا لأنني أستطيع."
   }
}

resp = requests.put(url, headers=headers, data=data)

شكرًا لكم!

يجب إرسال مفتاح الـ API واسم مستخدم الـ API كرؤوس منفصلة، وليس ضمن رأس Authorization. يجب أن يعمل شيء مثل هذا بشكل أفضل:

header = CaseInsensitiveDict()
header["Api-Key"] = 'longapikey'
header["Api-Username"] = 'myusername'

يبدو أن هذه نفس المشكلة التي واجهتها في موضوعك السابق:

إعجابَين (2)

شكرًا على ردك، ديفيد.

هذا أمر غريب جدًا، عندما قمت بتنسيق الرأس بالطريقة التي أوضحتها، حصلت على:

{"errors":["ليس لديك إذن لعرض المورد المطلوب. اسم مستخدم API أو المفتاح غير صالح."],"error_type":"invalid_access"}

إذا أضفت ["Authorization"]، فإن الأمر يعمل.

هذا لطلب GET بسيط، ولا يزال بإمكاني عدم تنفيذ PUT.

أتوقع أن يكون الرأس الذي يعمل لعملية واحدة فعالًا لجميع العمليات (بشرط أن يكون المفتاح عالميًا - وهو كذلك). لذا، أنا لست قلقًا بشأن الرأس في الوقت الحالي - أم يجب أن أكون؟

شكرًا!

من المرجح أن هناك خطأ في تنسيق طلب الـ PUT الخاص بك، خاصةً إذا كان طلب الـ GET يعمل بينما تقوم بذلك بالطريقة الخاطئة مع رأس Authorization. يعمل طلب الـ GET لأنك لا تحتاج إلى أي تفويض لإجراء طلب الـ GET. نحن لا ننظر حتى إلى رأس Authorization إذا قمت بإرساله. ستعمل طلبات الـ GET إلى النقاط العامة بشكل صحيح دون أي رؤوس.

إعجاب واحد (1)

@pedroleaoc إليك عينة صغيرة من سكريبت بايثون توضح كيفية إجراء طلبات مصادقة وكيفية إرسال بيانات الطلب لطلبات PUT/POST.

# discourse-api-demo.py
import requests
from requests.structures import CaseInsensitiveDict

# طلب GET أساسي إلى عنوان URL عام، لا حاجة لرؤوس.
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': "منشور رائع، لكن إليك تحديثًا لجسم المنشور", 'edit_reason': "قمت بتغيير هذا لأنني أستطيع." }

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)

ملاحظة: يتم تجاهل المعلمة json إذا تم تمرير data أو files.

سيؤدي استخدام المعلمة json في الطلب إلى تغيير Content-Type في الرأس إلى application/json.

إعجاب واحد (1)

أوه، طبعًا! ليست جميع طلبات GET تتطلب تفويضًا!
هذه تلميح رائع، سأبحث في ذلك. شكرًا لك!

الأشياء التي أعرفها بالفعل من خلال الهندسة العكسية:

  • api-key بدلاً من api_key
  • يتطلب طلب PUT القيمة "content-type": "application/x-www-form-urlencoded"
  • البيانات ليست بصيغة JSON (إنها مشفرة، على الرغم من أنني لم أتمكن من العثور على التشفير الصحيح)

يرجى الاطلاع على منشوري أعلاه مباشرةً. يمكنك استخدام json=data بدلاً من تنسيق data=data في طلبك، وستقوم مكتبة requests في بايثون بالاعتناء بـ content-type تلقائيًا وتعيينه كـ application/json، وهو ما يجب عليك استخدامه.

إعجابَين (2)

رائع، لقد أصبحت قادرًا الآن على تعديل منشوري! شكرًا لك على مساعدتك!

لكن لا يزال هناك مشكلة واحدة فقط؛ المفتاح الذي أستخدمه هو global. عندما أحاول استخدام مفتاح يحتوي على أذونات write وread فقط، أحصل على الرسالة: You are not permitted to view the requested resource. The API username or key is invalid.. عندما أقوم بتعديل المنشور عبر واجهة المستخدم الرسومية، يبدو أن هناك طلب PUT إلى عنوان URL للموضوع (بجانب الطلب الذي يقوم فعليًا بتعديل المنشور posts/post_id.json)، ولا يمكنني تكرار ذلك باستخدام مفتاح API محدود، بل فقط باستخدام المفتاح global. ومع ذلك، لا أفهم سببًا يمنعني من تعديل المنشور عبر API حتى بدون هذا الطلب PUT الإضافي الذي يحدث في واجهة المستخدم الرسومية.

تعديل: تقنيًا، يغطي مفتاح API الخاص بي /t/:slug/:topic_id، وهو المكان الذي يشير إليه طلب PUT.

هل قمت بتحديد نطاق “تحرير المنشورات” لمفتاح API الخاص بك؟

لا! ليس لدي حتى هذا الخيار! سأبحث في الأمر، شكراً لك مرة أخرى على المساعدة.

إعجاب واحد (1)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.