OOZOU
تواصلوا معنا
العودة إلى المدونة

رؤية المشكلة بعيون عملائكم عبر انتحال هوية العميل (Customer Impersonation)

أي موقع يقدّم دعمًا للعملاء سيواجه في النهاية مشكلة يصعب على العميل شرحها، أو يصعب فهمها دون رؤية ما يراه. ومع pretender gem يمكننا تسجيل الدخول إلى حساب المستخدم ورؤية ما يراه بالضبط.

29 يوليو 2020
6 دقائق للقراءة
رؤية المشكلة بعيون عملائكم عبر انتحال هوية العميل (Customer Impersonation)

طلب الدعم لحل مشكلة تواجهونها كعملاء تجربة مرهقة وبطيئة في الغالب، ويزداد الأمر سوءًا حين يكون البريد الإلكتروني الوسيلة الوحيدة للتواصل مع الدعم. ويمكننا تحسين هذه التجربة بتقليل الجهد الذي يبذله العميل لشرح مشكلته بالكامل. فحين لا يستطيع موظفو الدعم رؤية المشكلة التي يواجهها المستخدم، عليهم جمع كمّ كبير من المعلومات واستيضاح كل تفصيل صغير للتأكد من أنهم فهموا العميل بشكل صحيح. ويمكننا تقليل المعلومات المطلوبة بمنح موظفي الدعم القدرة على تسجيل الدخول إلى حساب العميل. في هذا المقال سأستخدم pretender لأتيح لموظفي الدعم تسجيل الدخول باسم مستخدمين آخرين. يعمل Pretender مع أي نظام مصادقة، وسأستخدم هنا devise

الدخول في وضع انتحال الهوية

أولًا لنتأكد من تعريف جميع الـ gems في ملف Gemfile:

gem 'devise'
gem 'pundit'
gem 'pretender'

ونحتاج أيضًا إلى إضافة مقتطف إلى كل controller نريد أن يتمكن موظفو دعم العملاء من استخدامه أثناء وضع انتحال الهوية. لنضفه إلى ApplicationController حتى نتمكن من انتحال الهوية في كل أجزاء التطبيق:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  impersonates :user
end

نحتاج إلى controller يتيح لموظفي الدعم الدخول في وضع انتحال هوية العميل والخروج منه:

class CustomerImpersonationsController < ApplicationController
  before_action :authenticate_customer_support_agent!

  def create
    user = User.find!(params[:id])
    impersonate_user(user)
    redirect_to root_path
  end

  def destroy
    # current_user is the impersonated user before we call
    # stop_impersonating_user so we should build the notice here or store the
    # current_user in a variable so we can fetch values from it later
    notice = "You are logged out as #{current_user.email}"
    stop_impersonating_user
    redirect_to root_path, notice: notice
  end

  private def authenticate_customer_support_agent!
    # If we're already impersonating a user, true_user will be the customer
    # support agent
    #
    # If we're not currently impersonating a user, current_user will be the
    # customer support agent
    return if (true_user || current_user)&.customer_support_agent?

    raise ActionController::RoutingError, 'Not Found'
  end
end

لا تنسوا إضافة الـ routes:

Rails.application.routes.draw do
  resource :customer_impersonation, only: %i[create destroy]
end

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

  1. نوفّر لموظف دعم العملاء نموذجًا يختار منه المستخدم ويرسله.
  2. ننشئ زرًا يستخدم طريقة POST لإرسال معرّف المستخدم.

معظم التطبيقات التي عملت عليها تحتوي على صفحة إدارة تعرض جميع المستخدمين المسجلين في جدول مقسّم إلى صفحات، لذا سنختار الخيار 2. وتنفيذه بسيط جدًا بفضل method الجاهزة link_to في Ruby on Rails، إذ يمكننا أن نطلب منها استخدام طريقة POST ثم نمرر معرّف المستخدم إلى المسار.

<table>
  <thead>
    <tr>
      <td>Name</td>
      <td>Email</td>
      <td></td>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.name %></td>
        <td><%= user.email %></td>
        <td>
          <%= link_to('Show', user) %>
          <%= link_to(
            'Impersonate',
            customer_impersonation_path(id: user.id),
            method: :post
          ) %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

إذا كانت لديكم عدة أدوار إدارية، فربما تفكرون في إنشاء pundit policy للتأكد من أن المسؤولين أصحاب الأدوار الصحيحة وحدهم يستطيعون انتحال هوية المستخدمين الآخرين. والآن بعد أن أصبح بإمكاننا انتحال هوية مستخدم، نحتاج أيضًا إلى القدرة على إيقاف ذلك. لدينا بالفعل الـ route والـ action في الـ controller، وبقي أن ننشئ رابطًا يتيح لمنتحلي الهوية تسجيل الخروج فعلًا. وعلينا أيضًا إزالة رابط تسجيل الخروج العادي، وإلا سيُسجَّل خروج المسؤول من حسابه هو. ولواجهة سلسة، يمكننا ببساطة استبدال رابط تسجيل الخروج الحالي برابط إيقاف انتحال الهوية الجديد.

<% if user_signed_in?  %>
  <%= link_to(
    'Log out',
    true_user ? customer_impersonation_path : destroy_user_session_path,
    method: :delete
  ) %>
<% end %>

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

هناك أمور أنصح بها بشدة لحماية عملائكم من الإجراءات غير المقصودة التي قد يتخذها موظفو الدعم. على الأرجح يتوقع عملاؤكم الخصوصية، لذا قد ترغبون في تبنّي سياسة تشترط طلب إذنهم قبل السماح للموظفين بالدخول إلى حساباتهم. ويمكنكم فعل ذلك عبر المحادثة أو البريد الإلكتروني، أو إنشاء نظام لطلب الإذن يُسجَّل داخل التطبيق. وأنصح بشدة أيضًا بتسجيل كل نشاط يجري أثناء انتحال الهوية. فإنشاء سجل تدقيق (audit trail) طريقة جيدة لحماية أنفسكم من الخطأ الذي سيقع حتمًا في المستقبل. ومع سجل التدقيق ستتمكنون من التحقق من الإجراء الصحيح الواجب اتخاذه حين يثير العميل المشكلة. وفي تطبيقاتنا نذهب أبعد من ذلك، فنسجّل كل طلب يرسله موظف دعم العملاء. لنضف ذلك إلى ApplicationController

bin/rails generate model AuditLog data:jsonb
class AuditLog < ApplicationModel
  belongs_to :user
end
class User
  has_many :audit_logs
end
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  after_action :log_impersonated_activity, if: :true_user
  impersonates :user

  private def log_impersonated_activity
    return unless true_user

    true_user.audit_logs.create!(
      data: {
        controller: params[:controller],
        action: params[:action],
        method: request.method,
        headers: headers,
        params: params,
        customer_id: current_user.id,
        customer_email: current_user.email,
        admin_id: true_user.id,
        admin_email: true_user.email
      }
    )
  end
end

وأنصح أيضًا بتقييد الإجراءات التي يستطيع موظفو دعم العملاء اتخاذها. نستخدم pundit عادة للتفويض (authorization)، لكن للأسف لم يُصمَّم pundit ليتعامل مع كائنَي مستخدم اثنين. ويمكننا إعادة تعريف pundit_user لنخبر pundit أين يجد كائن المستخدم، أي أن نمرر hash يحتوي على current_user وtrue_user، ثم نحدّث ApplicationPolicy ليعكس هذا التغيير.

class ApplicationController
  private def pundit_user
    { current_user: current_user, true_user: true_user }
  end
end
class ApplicationPolicy
  attr_reader :user, :true_user, :record

  def initialize(current_and_true_user, record)
    @user = current_and_true_user[:current_user]
    @true_user = current_and_true_user[:true_user]
    @record = record
  end

  protected def impersonating_customer?
    user.present? && user != true_user
  end
end

والآن يمكنكم في الـ policies الأخرى منح صلاحيات مختلفة أثناء وضع انتحال الهوية، كمنع موظفي دعم العملاء من إجراء المدفوعات مثلًا

class PaymentPolicy < ApplicationPolicy
  def create?
    !impersonating_customer?
  end
end

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

<% if true_user.present? %>
  <div class='banner danger warning'>
    You are signed in as <%= current_user.name %>.
    <%= link_to 'Stop impersonating', cutomer_impersonations_path(id: current_user.id), method: :delete %>
  </div>
<% end %>

ثم يمكننا إضافة رسائل تأكيد إلى كل الإجراءات المهمة:

<%= f.submit 'Save', data: { confirm: "Are you sure you want to save this item for #{current_user.name}'s account" } %>

وأنصح بتعطيل أي إجراءات يجب حمايتها:

<% if true_user %>
  <span class='disabled_impersonation'>Link account</span>
<% else %>
  <%= link_to 'Link account', link_account_path %>
<% end %>

وبهذا نختتم هذا الدليل. لقد تناولنا كل ما نحتاجه لنتيح لموظفي دعم العملاء تسجيل الدخول إلى حسابات عملائنا.

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

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

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد