لا يمكن تحديث البريد الإلكتروني عبر واجهة برمجة التطبيقات - خطأ invalid_access

Hi Guys,

Im getting an error when trying to use the API to update email.
I have looked at the logs and can see the following:

Started PUT “/discussion/users/davetest/preferences/email.json” for xx.xx.xx.xx at 2018-05-11 12:22:11 +0000

Processing by UsersEmailController#update as JSON

Parameters: {“api_key”=>;"[FILTERED]", “api_username”=>;“daveAdmin”, “email”=>;“[new.email@example.com](mailto:new.email@example.com)”, “username”=>;“davetest”}

Can’t verify CSRF token authenticity.

This is a PUT request, but looking at the scopes below, doesnt seem like PUT is supported for the WRITE scope? surely im misunderstanding, so could someone please assist?

I have re-generated the all-user api-key, also created specific user api-keys to use, but same result.

SCOPES = {
read: [:get],
write: [:get, :post, :patch],
message_bus: [[:post, ‘message_bus’]],
push: nil,
notifications: [[:post, ‘message_bus’], [:get, ‘notifications#index’], [:put, ‘notifications#mark_read’]],
session_info: [[:get, ‘session#current’], [:get, ‘users#topic_tracking_state’]]
}

Can you verify the content-type that you are making the API request as? It needs to be

"Content-Type: multipart/form-data;"

If it is not that content type you may see the CSRF token error.

Hi, thanks for the reply.
I actually had tried it both with ‘application/json’ and ‘application/x-www-form-urlencoded’ and neither worked. I have now tried it with what you suggested (via postman) and getting:

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

I have regenerated the global api key that is used for “all users” and using it with my own username, which is an admin too…

shahid

Here is an example of my postman request maybe you can spot any differences with what you are doing? I’m also using the “all users” key with an admin username.

yes, its the same, im using the Postman API collection supplied by discourse. So using it as suggested. I will try again tonight and see if i get any different results. Will update when ive tried. Thanks for assisting, much appreciated. Do let me know if you have any other idea.

أواجه هذه المشكلة أيضًا، وأتساءل عما إذا كانت لها علاقة باستخدام مزود OAuth لتسجيل الدخول، وبالتالي يتم حظر هذه الصفحة المحددة؟

من المرجح أن الأمر لا يتعلق بمزود OAuth لأن مفاتيح API ستتجاوزها.

هل يمكنك مشاركة كود طلب API الخاص بك؟

في بايثون:

import json
import requests
import time

my_token = ''

url_base = '<>'
update_email = url_base + "users/<my_username>/preferences/email.json"

headers = {
    "Content-Type": "multipart/form-data",
    'user-agent': 'my-app/0.0.1',
    'Api-Key': my_token,
    'Api-Username': '<my_username>'
}

data = {
  "email": "<new_email>"
}

response = requests.put(update_email, data=data, headers=headers)

print(response.text)

تعديل: كود مشابه جدًا لضبط المجموعات على المستخدمين وما إلى ذلك كان يعمل، لذا فإن مزيج المفتاح/اسم المستخدم (وهو مستخدم يتمتع بصلاحيات المسؤول) يعمل.

تعديل 2: أتوقع من تصفح آخر في المنتدى أن هذا يجب أن يتم مباشرة في قاعدة البيانات (أو بالأحرى عبر وحدة التحكم)، وهو أمر مستحيل بالنسبة لنا.

هل هناك أي أفكار أخرى حول هذا؟ شعوري هو أن شخصًا لديه صلاحيات وصول المسؤول يجب أن يكون قادرًا على تعيين البريد الإلكتروني لشخص ما.

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

هل تقصد أن واجهة المستخدم/واجهة برمجة التطبيقات يجب أن تتيح تعيين عنوان بريد إلكتروني للمستخدم إلى أي قيمة تريدها. (وليس أنك تعتقد أن هذا ممكن حاليًا.)

يمكنك بدء التغيير (عبر واجهة المستخدم وأعتقد أن ذلك متاح أيضًا عبر واجهة برمجة التطبيقات) عن طريق تعديل ملفه الشخصي وإدخال العنوان الجديد، لكن لن يتم تغييره إلا بعد النقر على الرابط في بريده الإلكتروني. هل هذا كافٍ؟ إذا لم يكن كذلك، فستحتاج إلى القيام بذلك من وحدة التحكم أو عبر إضافة.

بالضبط.

كلما أدخلت شيئًا في واجهة المستخدم لتعديل البريد الإلكتروني (والتي يمكنني الوصول إليها فقط عبر الرابط المباشر، أي https://<discourse>/u/<username>/preferences/email، ولا يوجد رابط عبر ملف المستخدم الشخصي)، يظهر لي أنه لا يمكنني القيام بذلك بعد النقر على “تغيير”:

وهذا يحدث على حسابي الخاص بصفتي مسؤولًا. ولا أستلم أي بريد إلكتروني.

وصلت إلى هذه النقطة الآن أيضًا…

@pfaffman: لقد ذكرت أنه من الممكن تغيير عنوان البريد الإلكتروني في الملف الشخصي، لكن هذا يتطلب تعيين email editable، أليس كذلك؟

لقد تعلمت أنه لا توجد طريقة لأي مدير أو استدعاء واجهة برمجة تطبيقات إدارية لبدء تغيير عنوان البريد الإلكتروني ما لم يُسمح للمستخدمين بتغيير عناوين بريدهم الإلكتروني أيضًا، أليس كذلك؟ يمكنني بالتأكيد العيش مع إرسال بريد إلكتروني للتأكيد وأن التغيير يحتاج إلى موافقة من المستخدم.

حالة الاستخدام الخاصة بي هي أن المستخدمين سيتم إدارتهم ضمن تطبيق آخر عبر واجهة برمجة التطبيقات. لذا، لا أريد أن يغيروا عناوين بريدهم الإلكتروني بأنفسهم، في discourse فقط.

هل يمكنك تنفيذ تسجيل الدخول الموحد وجعل تطبيقك الآخر مصدر تسجيل الدخول؟

هناك إعداد محدد لتسجيل الدخول الموحد يسمى sso overrides email يقوم بما تحاول تحقيقه. إذا قمت بإعداد تسجيل الدخول الموحد، فيمكنك بعد ذلك استخدام نقطة النهاية sync_sso وإرسال عنوان البريد الإلكتروني الجديد.

شكرًا لك @blake، هذا تحدٍ ممتع :wink:

سأضطر إلى استيراد كلمات المرور من Discourse إلى مركز الهوية … يا إلهي.

ساعدت في سيناريوهي الأصلي باستخدام عملية من ثلاث خطوات: تمكين تعديل البريد الإلكتروني، وبدء تغيير عنوان البريد الإلكتروني، وتعطيل تعديل البريد الإلكتروني. وهذا يبدو مبالغًا فيه بعض الشيء، لكنه يعمل.

سأفكر في سيناريو SSO.