مفاتيح API للمستخدم: تكرار client_id سيؤدي إلى خطأ في الخادم الداخلي

عند استدعاء user-api-key/new باستخدام client_id مستخدم بالفعل من قبل مستخدم آخر، سيُصدر المنتدى خطأ RecordNotUnique وسيفشل بصمت مع خطأ في الخادم الداخلي.

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint \"index_user_api_keys_on_client_id\"
DETAIL:  Key (client_id)=(893e0230d52455ea9b729334) already exists.
)
(eval):105:in `exec_params'
app/controllers/user_api_keys_controller.rb:66:in `create'

قد يرغب هذا في الفشل بشيء أقل صمتًا يبلغ المستخدم بوجود مفتاح واجهة برمجة تطبيقات بهذا المعرف العميل بالفعل.

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

5 إعجابات

دفعة سريعة للرؤية. لا نزال نرى هذه تظهر في نقطة النهاية /logs لدينا بشكل متكرر:

image

3 إعجابات

شكراً لإبلاغك عن هذا، لدي بعض الأسئلة للمساعدة في التحقيق في الأمر.

هل يمكنك تقديم مثال بسيط لتكرار هذا حتى أتمكن من تصحيح هذا محليًا؟ ما هي حالة الاستخدام الخاصة بك لمفاتيح واجهة برمجة تطبيقات المستخدم؟ هل تستخدم تطبيق الهاتف المحمول discourse hub أم شيئًا آخر؟

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

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

Code

// openssl genrsa -out keypair.pem 2048
$keypair = openssl_pkey_get_private(file_get_contents("keypair.pem"));

// الحصول على المفتاح العام
$public = openssl_pkey_get_details($keypair)["key"];

// بناء الاستعلام
$query = http_build_query([
    "auth_redirect" => "https://localhost/redirect",
    "application_name" => "Test repro",
    "client_id" => "7624a5376b7f52eb403a",
    "scopes" => "session_info",
    "nonce" => bin2hex(random_bytes(16)),
    "public_key" => $public
]);

$url = "https://forum.cfx.re/user-api-key/new?" . $query;
header("Location: " . $url);

الترخيص الأول والمتكرر سينجح كمستخدم أول، عند استخدامه مرة أخرى لمستخدم آخر دون تغيير client_id سيفشل.
image

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

بينما يجب أن يكون client_id فريدًا لعملاء اللعبة، بحيث يتم إدراج كل عميل كعميل منفصل في شاشة التطبيقات. بالنسبة لحالة استخدام الموقع، سترغب في الحصول على client_id واحد حتى لا يتم إدراج كل تسجيل دخول بشكل منفصل.

3 إعجابات

كنت أتساءل عما إذا كان هذا قد تم حله

هل كان هناك أي تحديث بخصوص هذا؟ لا يزال من غير الواضح ما إذا كان client_id يجب أن يكون فريدًا عالميًا بدلاً من أن يكون لكل مستخدم.

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

يجب أن يكون فريدًا عالميًا.

كيف ينبغي تنفيذ ذلك لحالات الاستخدام التي لا يمتلك فيها موقع ويب نظام مصادقة خاص به للمستخدمين ولا ينبغي له إنشاء تطبيقات API متعددة للمستخدمين؟

إعجابَين (2)

تعيين ملف تعريف ارتباط؟ أو تحديده عن طريق تجزئة شيء يحدد المستخدم (بالإضافة إلى شيء “سري” حتى لا يتمكن الأطراف الخارجية من تكراره)

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

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

يُطلق عليه معرف العميل وليس معرف المستخدم لأن المستخدم يمكن أن يكون لديه عملاء متعددون!

في معظم المعايير مثل OAuth، يُوصف معرف العميل بأنه “معرف التطبيق” ويمكن استخدامه لجميع المستخدمين (وليس لمستخدم واحد فقط)، على سبيل المثال، تسجيلات الدخول الاجتماعية لمنتداك تستخدم دائمًا نفس معرف العميل.

ومع ذلك، نظرًا لأن مفاتيح واجهة برمجة تطبيقات المستخدم مصممة في المقام الأول للعملاء مثل تطبيقات Discourse، فقد تم تصميمها لتكون فريدة، وسيكون من الجيد معرفة ما إذا كانت كذلك.

ستوضح الإجابة على ما سبق ما إذا كان هناك فحص مفقود في user_api_keys.rb أو فهرس خاطئ في قاعدة البيانات. لأن هذه الطلبات حاليًا تثير خطأ 500 مخيف وتظهر في نقطة النهاية /logs الخاصة بنا.

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

هل هناك أي تحديث بخصوص هذا؟ ما زلنا نرى المستخدمين يواجهون هذه المشكلة.

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

يجب أن يكون الخطأ أفضل، نعم، ولكن يجب أن يكون client_id فريدًا.

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