هل يمكنني كشف مسار بدون مصادقة؟

هل توجد طريقة لإنشاء مسار يتجاوز المصادقة؟

يُستخدم هذا للتكامل مع خدمات جهات خارجية.
والمتطلب هو توفير عنوان URL للخدمة (لا تُدعم الرؤوس أو الحمولات من أي نوع).
كان ذلك ممكنًا سابقًا بإضافة “?api_key=…&api_username=”، لكن هذه الميزة لم تعد متاحة.

تم استضافة مثيل Discourse بواسطةنا.

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

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

على سبيل المثال،

  # يسمح Rails 3.2 الافتراضي بالطلب مع جلسة فارغة
  # نحن هنا أكثر دقة ونقوم بإلغاء الجلسة / current_user
  # ثم رفع استثناء CSRF
  def handle_unverified_request
    # ملاحظة: مفتاح API سري، مما يلغي الحاجة إلى رمز CSRF
    unless is_api? || is_user_api?
      super
      clear_current_user
      render plain: "[\"BAD CSRF\"]", status: 403
    end
  end

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

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

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

عبر إضافة مكون (plugin)، يمكنك إضافة المسار الجديد الخاص بك إلى DiscoursePluginRegistry.api_parameter_routes، مما يتيح لك الاستمرار في تمرير بيانات اعتماد واجهة برمجة التطبيقات (API) عبر معاملات الاستعلام:

ستحتاج أيضًا إلى السطر التالي

skip_before_action :redirect_to_login_if_required

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

حسنًا، إذن تجاوز هذه الدالة وتخطّ الإجراء. سأحاول وأخبركم إذا نجحت.

افتراضيًا، نسمح فقط بترويسات إرسال بيانات اعتماد واجهة برمجة التطبيقات

  # ومع ذلك، في بعض السيناريوهات، من الضروري إرسالها عبر معلمات الرابط
  # لذا نحتاج إلى إضافة بعض الاستثناءات
  def api_parameter_allowed?
    request_method = @env["REQUEST_METHOD"]&.downcase&.to_sym
    request_format = @env['action_dispatch.request.formats']&.first&.symbol

    path_params = @env['action_dispatch.request.path_parameters']
    request_route = "#{path_params[:controller]}##{path_params[:action]}" if path_params

    if 'm_exposed#endpoint' == request_route && request_method == 'get'
      puts 'Allowed'
      return true
    end

    PARAMETER_API_PATTERNS.any? do |p|
      (p[:method] == "*" || Array(p[:method]).include?(request_method)) &&
      (p[:format] == "*" || Array(p[:format]).include?(request_format)) &&
      (p[:route] == "*" || Array(p[:route]).include?(request_route))
    end
  end

لقد قمت بذلك فقط لتقليل اختلافات git في المستقبل.

أيضًا، وحدة التحكم الخاصة بي:

# frozen_string_literal: true

class MExposedController < ::ApplicationController

  skip_before_action :redirect_to_login_if_required, raise: false

  def endpoint
    render json: { state: "hello world" }
  end

end

إذًا، الآن لا يتحقق نقطة النهاية من معلمات أو بيانات اعتماد الرؤوس.

كيف يمكنني جعلها تتحقق من مفتاح الـ API المقدم وتسمح بالوصول فقط إذا كان صالحًا؟ (مثلما كان يعمل سابقًا)

@riking @blake؟

أعتقد أن إضافة requires_login إلى وحدة التحكم الخاصة بك سيفي بالغرض. اطلع على بعض وحدات التحكم الأخرى في app/controllers للحصول على أمثلة.

حسناً، لم ينجح ذلك :slight_smile:

class MExposedController < ::ApplicationController

  requires_login

  skip_before_action :redirect_to_login_if_required, raise: false

تم الانتهاء مع خطأ 403 Forbidden

{"errors":["يجب أن تكون مسجلاً للدخول للقيام بذلك."],"error_type":"not_logged_in"}

هذا مُعلَن داخل إضافة.

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

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

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