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

كيف تطبّقون المصادقة بلا كلمة مرور في Ruby on Rails

تحدثنا مؤخرًا عن فوائد المصادقة بلا كلمة مرور. لنرَ الآن كيف نطبّقها عمليًا في Ruby on Rails.

31 ديسمبر 2020
4 دقائق للقراءة
كيف تطبّقون المصادقة بلا كلمة مرور في Ruby on Rails

في المقال السابق تحدثت عن فوائد المصادقة بلا كلمة مرور. وفي هذا المقال سأوضح كيف نطبّق رسائل البريد التي تحمل رابط تسجيل دخول سحريًا (magic link) في Ruby on Rails. لمن لا يعرف الفكرة: تتيح روابط تسجيل الدخول السحرية للمستخدم الدخول إلى حسابه من دون إدخال كلمة مرور. فبدلًا من النموذج التقليدي للبريد الإلكتروني وكلمة المرور، يكفي أن يُدخل المستخدم بريده الإلكتروني. يرسل النظام بعد ذلك رابطًا يحتوي على token مرتبط بحسابه. وعندما ينقر المستخدم على الرابط، ينتقل إلى التطبيق ويُسجَّل دخوله إلى حسابه مباشرة. وبهذه الطريقة يمكننا أيضًا تسجيل دخوله في التطبيقات الأصلية (native) باستخدام deeplinks.

لنكتب بعض الكود

أول ما نحتاج إليه هو إضافة عمود جديد إلى جدول Users لتخزين login tokens. سنستخدم UUIDs لتبسيط عملية التوليد.

rails g migration add_login_token_to_users login_token:uuid

لننشئ الآن controller يتولى عمليات تسجيل الدخول. لن يكون هذا الـ controller متوافقًا تمامًا مع RESTful، لأننا لا نستطيع إرسال طلب POST من برنامج البريد لدى المستخدم. عادةً أستخدم magic_logins_controller حتى نحتفظ بـ sessions controller لتسجيل الدخول بكلمة المرور، إن أردنا يومًا الجمع بين الطريقتين.

class MagicLoginsController < ApplicationController
  def new; end

  def create
    if (user = User.find_by(login_token_params))
      user.generate_login_token!
      LoginMailer.with(user: user).magic_login_email.deliver_later
      redirect_to(new_magic_login_path, notice: 'Please check your inbox')
    else
      redirect_to(new_magic_login_path, alert: 'It looks like that email is not registered')
    end
  end

  private def login_token_params
    params.require(:login_token).permit(:email)
  end
end
Rails.application.routes.draw do
  resources :magic_logins, only: %i[new create]
end

لنُضف view للـ action المسمّى new. لن أضيف أي تنسيق، ويمكنكم تنسيقه كما تشاؤون، سنكتفي بنموذج بسيط كمثال.

<%= form_for(User.new, url: magic_logins_path, method: :post do %>
  <%= f.label :email %>
  <%= f.email_field :email %>
  <%= f.submit 'Send me a magic login link' %>
<% end %>

بعد ذلك نحتاج إلى إضافة method في الـ model المسمّى User لتوليد token جديد.

class User < ApplicationRecord
  def generate_login_token!
    update_column(:login_token, SecureRandom.uuid)
  end
end

لا نحتاج إلى أي تحقق هنا لأننا نستخدم UUIDs، فنحن في أمان. حسنًا، لننشئ الآن _magic_login_email. _

class LoginMailer < ApplicationMailer
  def magic_login_email
    user = params[:user]
    @magic_login_url = magic_logins_url(token: user.login_token)
    mail(to: user.email, subject: "Here's your login link")
  end
end
<h1>Here's your login link</h1>
<%= link_to 'Log in now', @magic_login_url %>

ربما لاحظتم أننا نستخدم رابط index ونمرّر الـ token في query string. هناك طرق أخرى لفعل ذلك، لكن هذا النهج بسيط ويتماشى مع ما يوفّره Rails أصلًا. وهو بالطبع يخالف مبادئ RESTful، لذلك قد تفضّلون نهجًا آخر. الآن لم يبقَ سوى إضافة منطق تسجيل دخول المستخدمين. سأفترض أنكم تستخدمون Devise. إن كنتم تستخدمون gem آخر أو تديرون الجلسات يدويًا، فستحتاجون إلى تعديل هذا المنطق.

class MagicLoginsController < ApplicationController
  def index
    redirect_to root_path unless params[:token].present?

    user = User.find_by(login_token: params[:token])
    if user
      sign_in(user)
      user.update_column(:login_token, nil)
      redirect_to after_sign_in_path, notice: 'Logged in successfully!'
    else
      redirect_to new_magic_login_path, alert: 'The link you used was invalid. Please request a new login link'
    end
  end
end

كما ترون، نسجّل دخول المستخدم ثم نحذف login token من قاعدة البيانات، وهذا يمنع استخدام الـ token أكثر من مرة. أصبح كل شيء مترابطًا، ويمكن للمستخدمين الآن تسجيل الدخول عبر الروابط السحرية. وقد ترغبون أيضًا في تحديد مدة صلاحية الـ tokens. لفعل ذلك يكفي أن نضيف عمودًا آخر لتتبّع وقت إنشاء الـ token والتحقق من أنه لم تنتهِ صلاحيته

rails g migration add_login_token_generated_at_to_users login_token_generated_at:datetime
class MagicLoginsController < ApplicationController
  def index
    redirect_to root_path unless params[:token].present?

    user = User.find_by(login_token: params[:token])
    if user
      if user.login_token_generated_at < 15.minutes.ago
        redirect_to new_magic_login_path, alert: 'The link you used has expired. Please request a new login link'
      end
      sign_in(user)
      user.update_column(:login_token, nil)
      redirect_to after_sign_in_path, notice: 'Logged in successfully!'
    else
      redirect_to new_magic_login_path, alert: 'The link you used was invalid. Please request a new login link'
    end
  end
end
Rails.application.routes.draw do
  resources :magic_logins, only: %i[index new create]
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. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد