مواصفات مفاتيح واجهة برمجة التطبيقات للمستخدم

يحتوي Discourse على نظام لتوليد مفاتيح API لكل مستخدم إذا تم اتباع بروتوكول محدد للغاية. يسهّل هذا الميزة وصول “التطبيقات” إلى مثيلات Discourse دون الحاجة إلى إشراك المشرفين.

وصف عالي المستوى

على مستوى عالٍ:

  1. يقوم العميل (تطبيق سطح المكتب، إضافة المتصفح، تطبيق الهاتف المحمول) بتوليد زوج من المفاتيح الخاصة/العامة وعنوان URL للعودة.

  2. يعيد العميل التوجيه إلى مسار على Discourse ليمنح Discourse مفتاحه العام.

  3. يحصل Discourse على موافقة المستخدم لاستخدام التطبيق.

  4. يولد Discourse مفتاح API للمستخدم.

  5. يعيد Discourse التوجيه إلى عنوان URL للعودة مع حمولة مشفرة باستخدام مفتاح API العام الذي يحتوي على مفتاح API للمستخدم.

التفاصيل

حالات الاستخدام:

  1. تطبيقات سطح المكتب التي تستعلم مواقع Discourse نيابة عن المستخدمين النهائيين للحصول على أعداد الإشعارات عبر مواقع متعددة.

  2. تطبيقات الهاتف المحمول التي تستعلم مواقع Discourse نيابة عن المستخدمين النهائيين وتتعامل مع إشعارات الدفع.

  3. تطبيقات الويب التي توفر لوحة معلومات للمستخدمين النهائيين حول مواقع Discourse المختلفة.

  4. تكاملات مخصصة مع تطبيقات الجهات الخارجية التي تستهلك Discourse كجزء من تطبيق الشركة العام. على سبيل المثال: دمج إشعارات مجتمع Discourse في تطبيق hopscotch.

التصميم:

إعدادات الموقع

  • allow_user_api_key_scopes: نطاقات الوصول المسموح بها لمفاتيح API للمستخدم. يتم تعريف النطاقات هنا. النطاقات المدمجة المتاحة هي: read (قراءة)، write (كتابة)، message_bus (حافلة الرسائل)، push (دفع)، one_time_password (كلمة مرور لمرة واحدة)، notifications (إشعارات)، session_info (معلومات الجلسة)، bookmarks_calendar (تقويم العلامات المرجعية)، user_status (حالة المستخدم) (قد تسجيل الإضافات نطاقات إضافية).

  • user_api_key_allowed_groups: يتحكم في المجموعات المسموح لها بتوليد مفاتيح API للمستخدم (الإعدادات الافتراضية هي المشرفون، والمعتدلون، ومستوى الثقة 0).

  • allowed_user_api_push_urls: قائمة بالمواقع التي يمكن أن تكون أهدافًا لإشعارات الدفع.

  • allowed_user_api_auth_redirects: وجهات إعادة التوجيه المسموح بها بعد توليد مفتاح API للمستخدم.

الإعدادات العامة

  • max_user_api_reqs_per_minute: 50
  • max_user_api_reqs_per_day: 4000

عناصر واجهة المستخدم

إذا تم منح أي مفاتيح API للمستخدم، يعرض Discourse علامة تبويب تطبيقات في صفحة المستخدم.

ستقوم علامة تبويب تطبيقات بإدراج:

  • اسم التطبيق على سبيل المثال: (“Discourse Notifier”)
  • تاريخ آخر استخدام
  • تاريخ الموافقة
  • قائمة بنطاقات الوصول الممنوحة
  • زر سحب الوصول حتى تتمكن بسهولة من سحب أي مفاتيح

واجهة تفويض مفتاح API

يجب تفويض كل مفتاح صراحةً من قبل المستخدمين النهائيين في صفحة تشرح بوضوح ما يحدث، على سبيل المثال:

يطلب “Discourse Notifier” الوصول التالي إلى حسابك:

  • قراءة الإشعارات ومسحها
  • قراءة معلومات جلسة المستخدم
  • إنشاء رمز تسجيل دخول لمرة واحدة

[تفويض]

تدفق توليد مفتاح API

يتطلب API طلب GET واحد فقط من جانب المستخدم.

https://sitename.com/user-api-key/new

:exclamation: اعتبارًا من Discourse 2.1، تنتهي صلاحية مفاتيح API للمستخدم هذه تلقائيًا إذا تُركت دون استخدام لفترات طويلة. يتم تعيين إعداد الموقع: revoke user api keys unused days (أيام عدم استخدام مفاتيح API للمستخدم لسحبها) إلى 180 افتراضيًا.

المعاملات:

  • auth_redirect: عنوان URL لإعادة التوجيه إليه مع الرمز المُنشأ.
  • application_name: اسم التطبيق الذي يقدم الطلب (سيتم عرضه في علامة تبويب التطبيقات في حساب المستخدم).
  • client_id: معرّف فريد للعميل.
  • nonce: رقم عشوائي فريد يولده العميل. سيتم إعادته في الحمولة المشفرة حتى يتمكن العميل من التحقق من صحة الاستجابة.
  • scopes: قائمة مفصولة بفواصل بنطاقات الوصول المسموح بها للمفتاح، انظر allow user api key scopes (السماح بنطاقات مفاتيح API للمستخدم) للحصول على القائمة الكاملة للنطاقات المتاحة.
  • push_url: عنوان URL لإرسال إشعارات الدفع إليه (مطلوب وصالح فقط إذا تم تضمين push أو notifications في النطاقات).
  • public_key: الجزء العام من زوج المفاتيح الذي يولده العميل.
  • padding (اختياري): وضع تعبئة RSA المستخدم لتشفير الحمولة. القيم المقبولة هي pkcs1 (الافتراضي) أو oaep. يُوصى بـ OAEP للتطبيقات الجديدة.

بعد استدعاء /user-api-key/new بالمعاملات الصحيحة، قد يحدث أمران:

  1. إذا لم يكن المستخدم مسجل الدخول، سنعيد التوجيه إلى تسجيل الدخول (بعد تسجيل الدخول سنستأنف التفويض).
  2. بمجرد تسجيل دخول المستخدم، سيتم عرض واجهة التفويض عليه.

بعد السماح بالتفويض، سيعيد النظام التوجيه إلى عنوان URL المحدد في auth_redirect ويتضمن معلمة payload مشفرة تحتوي على كائن JSON مع مفتاح API للمستخدم المُنشأ (key)، وnonce، وحالة الدفع (push)، وإصدار API (api). إذا تم طلب نطاق one_time_password (كلمة مرور لمرة واحدة)، فسيتم أيضًا تضمين معلمة استعلام oneTimePassword مشفرة منفصلة. لا يتم إعادة client_id لأمان إضافي.

التحقق من إصدار API

يتم إصدار API لمفتاح المستخدم في Discourse. يمكن للعملاء التحقق من إصدار API لموقع Discourse عن طريق تقديم طلب HEAD إلى https://sitename.com/user-api-key/new. ستحتوي الاستجابة على رأس باسم Auth-Api-Version يحتوي على رقم إصدار API للموقع.

استهلاك API

سيكون استهلاك API للعميل مختلفًا بعض الشيء عن API المسؤول الحالي.

يمكن للعميل تحديد رأسين:

User-Api-Key (مطلوب): المفتاح الذي تم إنشاؤه

و

User-Api-Client-Id (اختياري): قم بتزويده لتحديث ‘معرف العميل’ المخزن لهذا المفتاح في قاعدة البيانات.

بمجرد تحديد هذه الرؤوس، يمكن للعميل تنفيذ طلبات ضد API كما هو معتاد.

إنشاء كلمة مرور تسجيل دخول لمرة واحدة

اعتبارًا من الإصدار 4، يتضمن API نطاقًا خاصًا: نطاق one_time_password، والذي يسمح للعملاء باستخدام مفتاح API للمستخدم لإنشاء كلمة مرور لمرة واحدة. إذا تضمن العميل هذا النطاق عند إنشاء مفتاح API باتباع الخطوات أعلاه، فسيتم تضمين oneTimePassword مشفر كمعلمة استعلام منفصلة في إعادة التوجيه إلى العميل.

بديلًا لذلك، يمكن للعميل تقديم طلب GET إلى /user-api-key/otp بالمعاملات التالية:

  • auth_redirect
  • application_name
  • public_key
  • padding (اختياري)

ومع رأس User-Api-Key.

سيعيد هذا الطلب التوجيه إلى شاشة في Discourse ستطلب من المستخدم السماح للتطبيق بالوصول إلى الموقع. إذا وافق المستخدم، سيعيد الموقع التوجيه إلى عنوان URL المحدد في auth_redirect ويتضمن معلمة oneTimePassword مشفرة تحتوي على كلمة مرور لمرة واحدة يمكن للعميل استخدامها لتسجيل الدخول إلى الموقع عن طريق طلب https://sitename.com/session/otp/ONE-TIME-PASSWORD. (كلمة المرور لمرة واحدة صالحة لمدة 10 دقائق فقط.)

سحب مفاتيح API

لإلغاء مفتاح API، قدم طلب POST مع رأس User-Api-Key وبدون معاملات إلى /user-api-key/revoke.


آخر مراجعة بواسطة @SaraDev في 2022-07-13T00:00:00Z

31 إعجابًا
Generating User Api Keys with REST API
Discourse Login & Registeration
Discourse sso login using Rest API
Custom Push Notifications: allowed user api push urls
Beta testing the iOS mobile app
How can I get user details via the user api key?
Authorization from a desktop application (and base domain site)
Secure way of encrypting payload in Javascript for user authentification
Can non-admin user issue their own API key?
Automatic Login from iOS/Android app
Delegated authentication for Discourse Mobile app
Generating User Api Keys with REST API
Generating User Api Keys with REST API
API CORS Headers Incorrect
Get back Username with API Key?
Is there any documentation on the User/Mobile API?
Passing draft text into a new response
Discourse Hub "connect"
Generate User API Keys for testing
Consolidated API Requests in the thousands yet our site has no active API keys listed, is this a concern?
Having issue accessing the Discourse APIs from react app
Discourse REST API Documentation
Having issue accessing the Discourse APIs from react app
CORS error accessing API from javascript application
Does Discourse have support for PAT tokens?
API key creation
Access via Discourse API, key and/or user rejected
Feasibility of allowing a User Api Key client to register a valid auth_redirect
Implement discourse Apple login using API
Thousands of user api requests and invalidation
Are User API Keys Not Generated When Logging in via Login Link?
Confusion about API Authenticated User
Confusion about API Authenticated User
Generate User Api Key Without User Approval
How to use discourse api in react native?
"Api-Key" and "Api-Username" for try.discourse.org?
How can I allow users to like posts using RESTapi
Allow_user_api_key这个设置在哪开启
Dexo - A Native iOS Client for Discourse
Acess-Control-Allow-Headers CORS Error with API after updating discourse
CORS error accessing API from javascript application
Clip To Discourse Chrome Extension - now with User API capability!
Unable to create "Single User" level API key, always defaults to "All Users"
Discourse index
Clip To Discourse Chrome Extension - now with User API capability!
Authentication Protocol re: App Integration
Embed Discourse in a native app?
Request header field User-Api-Key is not allowed by Access-Control-Allow-Headers
Request header field User-Api-Key is not allowed by Access-Control-Allow-Headers
Request header field Content-Type is not allowed by Access-Control-Allow-Headers
Create apikey for user programmatically as admin
How to fix 'Cannot read property '_links' of undefined'
Allow API use by regular users, not just admins
The purpose of the 2 Discourse API systems
Bot writer's tip: Processing every post
Using Zapier without being admin
Per User API Keys Not Working
Acess-Control-Allow-Headers CORS Error with API after updating discourse
Work with discourse users on an SPA

There are places I’ve strongly considered writing a delayed post tool, so I can compose a bunch of “word of the day” type things to keep going while I’m on vacation. Doing it without proper API access and pretending to be a browser seems somewhat more complicated than on other forum software.

(Just as an example of another use case.)

That is a good example, but keep in mind, our default will be only to enable read tokens, not write ones. Site admins will have to opt to allow write tokens.

Completely agree that the _t cookie hacks are a huge problem.

إعجابَين (2)

Does max_user_api_calls_per_key_day setting apply to admin-created keys at /admin/api?

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

Nope only to user api keys, we can look at adding extra limits for standard Api keys, it is a good safeguard

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

To be clear, this is not implemented yet, correct?

No, it’s there (for almost 2,5 years now) - Admin - Settings - User API.

4 إعجابات

As of Discourse 2.1 these user api keys now auto-expire if left unused for long periods of time, correct @sam?

إعجابَين (2)

Correct the site setting: expire user api keys days is set to 180 out of the box.

إعجابَين (2)

Okay, but you have to have admin access to see that page yes? And as an admin, it seems I can only create 1 key, so can’t create many keys for different users. confused.

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

What are you trying to accomplish? It’s not clear because there is this (user api keys) and regular API tokens (which is what I think you are after) that admins can create for multiple users, but you have to do that from the individual user’s page inside of the admin dashboard by clicking on the “generate” button on the “API Key” field.

4 إعجابات

Thanks! Yes, “regular API tokens” for users is what i was after. I’m sure I’d seen that a million times, and never realized it was there. :heavy_check_mark:

3 إعجابات

Hey everyone I’m not sure if this was resolved? I see that it’s possible to create an “All Users” and (per user) level API token as an admin, but I’m interested in giving a user the power to generate his/her own token. Has there been work done on this? It sounds like the original thread was getting at this idea, and then it was lost. Thanks!

Download the mobile App and then add a site, that uses the user api key system you have to follow a very strict workflow, no plans to expose arbitrary generation of keys in user prefs

3 إعجابات

Thank you! I downloaded the app, and then realized that the sites I belong to don’t have this enabled (I’ve been testing on my local machine with the Dockerized discourse). Just to make sure we are talking about the same thing - I’m interested in generating tokens to use just a scoped subset of functions (and not global API keys to do all the things). Is this what you are talking about?

It seems like, given that there is an endpoint to generate tokens, it would be logical to provide this function (to users with a certain trust level, for example) from within the site. Otherwise, it would need to be the case that the site generates some external page (with a server to hide an admin token) to generate the keys for the user. Is it the case that 1. there is no internal generation of tokens for the user (and why not?) and 2. Nobody has created some external app (javascript, flask, anything really) to perform this action?

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

Yes.

Possibly, conceptually

  1. This is tricky to consume cause you need to use custom HTTP headers (by design)

  2. It would be very hard to educate even TL3 users about what the point is of this thing.

I prefer not to ship UI for this in core, but maybe you should write a plugin for your specific use case?

Can you explain a bit more about the “why” here?

The design of the system centers around “I have an external dedicated program”, “this program knows how to follow Discourse protocol”, “It asks for token”

API keys (non user ones) are much easier to consume cause you just append them after the ?

4 إعجابات

Can I pass the API key generated from the user page on this? I was trying to use that API key and seeing ‘You are not permitted to view the requested resource.’ error on /categories.json API request

مرحباً يا أصدقاء

عذراً إذا كان هذا تكراراً، لكنني أواجه صعوبة في استيعاب الخطوات المذكورة، رغم أنها مُنظمة بشكل ممتاز.

لدي تثبيت لـ Discourse على https://forum.domain.com وموقع على https://development.domain.com، وأحتاج من خلاله إلى إجراء مكالمات لتثبيت Discourse لجلب بعض البيانات وتحديد بعضها.

جميع الطلبات تعمل بنجاح من Postman باستخدام Api-Username وApi-Key دون أي مشكلة.

لكن في حالة طلبات Cross-Origin باستخدام JavaScript، لا يسمح Discourse باستخدام Api-Username، مما دفعني إلى اتباع المسار الموصوف في هذا الموضوع، أي استخدام User-Api-Key وUser-Api-Client-Id.

أحتاج بشكل أساسي إلى وصف للمعاملات PUBLIC_KEY وNONCE وCLIENTID المستخدمة في الطلب النموذجي أدناه، وإلى أين يمكنني الحصول عليها…

https://forum.domain.com/user-api-key/new?public_key=PUBLIC_KEY&nonce=NONCE&scopes=SCOPES&client_id=CLIENTID&application_name=DEVELOP&auth_redirect=XXX

وأخيراً، هل تسمح هذه العملية بإجراء طلبات API سلسة من https://development.domain.com إلى https://forum.domain.com دون الحاجة إلى مصادقة؟

ملاحظة: لقد قمت بإعداد SSO بين المنتدى والموقع الذي تُجرى منه الطلبات، لذا سيكون المستخدم مسجّلاً الدخول.

شكراً لأي توجيهات.

لحظة واحدة، هل هذا أمر خاص بكل مستخدم؟ هل تسمح لمستخدمين عشوائيين بفعل ذلك؟

يدعم واجهة برمجة التطبيقات (API) الخاصة بخادمنا الآن المصادقة القائمة على الرؤوس، لذا يمكنها العمل مع CORS تمامًا كما تفعل مفاتيح API الخاصة بالمستخدمين. يمكنك استخدام مفاتيح API الخاصة بالمستخدمين إذا كنت ترغب في تقييد النطاقات والسماح للمستخدمين النهائيين بإنشاء المفاتيح بدلاً من المسؤولين.

إعجابَين (2)

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

يمكنني استهلاك الـ API دون مشكلة عبر Postman. على سبيل المثال، طلب GET إلى /notifications.json?username=alanmurphy يعيد البيانات دون مشكلة باستخدام api-key فقط كعنوان.

إذا قمت بتفعيل هذا الطلب من وحدة تحكم تثبيت Discourse، فسأحصل على البيانات دون مشكلة أيضًا، أي:

var xhr = new XMLHttpRequest();
xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open(“GET”, “https://**********.com/notifications.json?username=alanmurphy”);
xhr.setRequestHeader(“api-key”, “d06ca53322d1fbaf383a6394d6c229e56871342d2cad953a0fe26c19df7645ba”);
xhr.setRequestHeader(“api-userame”, “system”);
xhr.send();

كل شيء على ما يرام:+1:

ومع ذلك، إذا قمت بذلك من النطاق الفرعي الذي أود من خلاله الاتصال بـ Discourse، فإن النظام يخبرني بأنه تم حظره بسبب سياسة CORS: حقل الرأس api-key غير مسموح به بواسطة Access-Control-Allow-Headers.

العناوين المسموح بها هي:

Content-Type, Cache-Control, X-Requested-With, X-CSRF-Token, Discourse-Visible, User-Api-Key, User-Api-Client-Id

إذا كان بإمكانك تزويدي بإرشادات حول معاملات المصادقة التي يجب تمريرها لطلبات ما بين النطاقات وأين يمكن الحصول عليها، فسيكون ذلك مفيدًا جدًا.

ملاحظة: تم إعداد Discourse للسماح بطلبات ما بين النطاقات من النطاق، لذا أعتقد أن المشكلة تتعلق فقط بالعناوين.

شكرًا لك

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