التسجيل والدخول عبر API مخصصة - هل سيعمل بشكل صحيح؟

في حالتنا، لدينا حاجة لاستخدام Discourse كواجهة خلفية فقط (شبه نظام إدارة محتوى).

لقد عرضت مسارات التسجيل وتسجيل الدخول باستخدام:

skip_before_action :redirect_to_login_if_required, raise: false
skip_before_action :verify_authenticity_token, raise: false

… وسُمح للمسارات في دالة api_parameter_allowed?. في النسخة النهائية، سأضيف نوعًا من الملح (salt) لزيادة الأمان قليلاً، لكن هذا مجرد مسودة.

… واستخدمت الكود أدناه.

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

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

أستخدم هذا الكود لإنشاء مستخدم:

      normalized_username = User.normalize_username(username)
    rescue
      normalized_username = nil
    end
    raise PluginError.new(:invalid_signup_username) if !normalized_username.present? || User.username_exists?(normalized_username) || User.reserved_username?(normalized_username)

    # حاول بهذا الشكل
    raise PluginError.new(:invalid_signup_email) if (existing_user = User.find_by_email(email))

    begin
      new_user = User.new
      new_user.name = first_name
      new_user.email = email
      new_user.password = password
      new_user.username = username
      new_user.active = false
      new_user.approved = true
      new_user.approved_by_id = -1
      new_user.approved_at = DateTime.now

      new_user.password_required!

      new_user.save

      new_user.email_tokens.create(email: email) unless new_user.email_tokens.active.exists?
      if (email_token = new_user.email_tokens.active.where(email: email)&.first)
        EmailToken.confirm(email_token.token, skip_reviewable: true)
      end

      new_user.update!(active: true)
    rescue => e
      raise e
    end

أستخدم هذا الكود لتسجيل مستخدم:

new_user = self.class.commit_user_to_db(first_name, email, password, username)

    raise PluginError.new(:error_creating_user_discourse) unless new_user.present? && new_user.is_a?(User) && new_user.approved?

    user_api_key = UserApiKey.create!(
      application_name: "#{application_name}-v#{version}",
      client_id: client_id,
      user_id: new_user.id,
      push_url: "https://api.discourse.org/api/publish_#{platform === Constants::PLATFORMS[:ios] ? 'ios' : ''}#{platform === Constants::PLATFORMS[:android] ? 'android' : ''}",
      scopes: %w[notifications session_info read write message_bus push]
    )

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

    email = params[:email]&.to_s
    password = params[:password]&.to_s

    return render json: PluginError.new(:invalid_login_email) unless email.present?
    return render json: PluginError.new(:invalid_login_password) unless password.present?

    user = User.joins(:user_emails).where({ user_emails: { email: email } })&.first
    return render json: PluginError.new(:invalid_login_email) unless user.present?

    return render json: PluginError.new(:invalid_login_password) unless user.confirm_password?(password)

    # احذف أي مفاتيح قديمة كانت لدينا لهذا المعرف الخاص بالعميل (client_id)
    UserApiKey.where(user_id: user.id, client_id: client_id).destroy_all

    user_api_key = UserApiKey.create!(
      application_name: "#{application_name}-v#{version}",
      client_id: client_id,
      user_id: user.id,
      push_url: "https://api.discourse.org/api/publish_#{platform === Constants::PLATFORMS[:ios] ? 'ios' : ''}#{platform === Constants::PLATFORMS[:android] ? 'android' : ''}",
      scopes: %w[notifications session_info read write message_bus push]
    )

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