كيفية مصادقة / تخويل مستخدم مجهول لفترة محدودة؟

9

لنفترض أن لدي كيان فاتورة. تنتمي الفاتورة إلى بعض المستخدمين ( invoices.user_id ).

إذا دخل المستخدم myapp.com/invoices/1 يحتاج لتسجيل الدخول للوصول إلى فاتورته. هذا طبيعي جدا.

بعض الأحيان invoices.user_id فارغ (مالك الفاتورة ليس لديه حساب في نظامنا) ، ولكن لدينا invoices.phone_number عمود.

الهدف هو إنشاء نظام مصادقة يستند إلى التحقق من رمز SMS للمستخدمين الذين ليس لديهم الحساب في نظامنا. إذا أكد المستخدم أنه يمتلك بالفعل رقم هاتف مرتبط بالفاتورة (التحقق من الرمز) ، فأنا أريد منحه حق الوصول المؤقت (15 دقيقة) إلى صفحة تفاصيل الفاتورة هذه (وهذه الصفحة فقط).

كانت فكرتي الأولى استخدام رمز JWT المخزن في الجلسة.

كانت فكرتي الثانية استخدام جدار حماية مخصص.

هل هناك نهج أفضل؟

2 الاجابة

7
افضل جواب

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

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

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

أما بالنسبة للمصادقة نفسها ، فانتقل إلى حارس مخصص ، حيث يمكنك التحكم بشكل كامل في كيفية عمل عملية المصادقة.

:مؤلف
2
افضل جواب

يمكنك مصادقة مستخدم وهمي لمدة 15 دقيقة باستخدام الإجراء التالي:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    /**
     * confirm that the user indeed owns 
     * phone number related to the invoice (code verification)
     */

    //create a user for this task only and fetch it
    $user = $em->getRepository(User::class)->find(1);

    //firewall name used for authentication in security.yml
    $firewall = "main_secured_area";

    $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
    $this->get('security.token_storage')->setToken($token);
    $this->get('session')->set("_security_$firewall", serialize($token));

    //$lifetime takes number of seconds to define session timeout 15min = 900sec
    $this->container->get('session')->migrate($destroy = false, $lifetime = 900);

    //fire the login event manually
    $event = new InteractiveLoginEvent($request, $token);
    $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

    return $this->render('default/index.html.twig');
}
:مؤلف
فوق
قائمة طعام