صفحه‌های پلتفرم امضای دیجیتال

پلتفرم امضای دیجیتال

ایران فاوا گسترش · گروه صنعتی ایران‌خودرو

نقش
مهندس ارشد فرانت‌اند - سرپرست فرانت‌اند
دوره
۱۴۰۵ - اکنون
نوع
سازمانی
  • React 19
  • Vite
  • React Compiler
  • TanStack Query
  • FIDO2 / WebAuthn
  • IranSign PKI
  • eKYC
  • OIDC / SSO
  • MediaRecorder
  • react-pdf

اپی که مشتری وقتی یک خرید - بیشتر از همه قرارداد خودرو - به امضای حقوقی نیاز دارد باز می‌کند. او را از احراز هویت عبور می‌دهد، گواهی امضایی وابسته به گوشی‌اش صادر می‌کند و بعد قراردادهایی را که منتظرش هستند فهرست می‌کند: پیش‌نمایش، دانلود، امضا. احراز هویت و گواهی روی سرویس‌های ایران‌ساین اجرا می‌شوند، استعلام هویت روی سامانه‌های ملی، و قراردادها از پلتفرم خود گروه می‌آیند؛ این اپ تنها جایی است که همه‌ی این‌ها به کاربر می‌رسند.

چالش

یک وب‌اپ موبایل برای صدور گواهی امضای دیجیتال و امضای قراردادها با آن: سه سطح احراز هویت که به زنده‌سنجی ختم می‌شود، گواهی‌ای که با یک اعتبارنامه‌ی FIDO2 به گوشی گره خورده، و زیرساخت کلید عمومی (PKI) ایران‌ساین در پشت آن.

فرایندهای امضا به شکلی خاص شکست می‌خورند: همان مرحله‌ای هستند که کاربر به احتمال زیاد رها می‌کند، و همان مرحله‌ای که کمترین آزادی را برای ساده‌سازی دارید. احراز هویت، صدور گواهی و امضا هر کدام با یک سیستم خارجی سروکار دارند که تأخیر خودش، حالت‌های خطای خودش و تعریف خودش از «نشست» را دارد. گواهی روی یک گوشی زندگی می‌کند، پس یک حساب می‌تواند روی سرور کاملاً احراز شده باشد و باز هم روی گوشی‌ای که در دست کاربر است نتواند امضا کند. مرحله‌ی زنده‌سنجی از مرورگر گوشی می‌خواهد ویدئویی ضبط کند که سرور بپذیرد - و سافاری و کروم درباره‌ی چگونگی‌اش هم‌نظر نیستند. و هیچ‌چیز در این فرایند را نمی‌شود سرهم‌بندی کرد: یک وضعیت مبهم در رابط امضا یک مشکل حقوقی است، نه یک گلایه‌ی تجربه‌ی کاربری.

کاری که کردم

  • پروژه را راه‌اندازی کردم - React 19 روی Vite با React Compiler، TanStack Query برای وضعیت سرور، oxlint - و ساختارش را چیدم: یک صفحه برای هر سطح احراز هویت، یک ماژول API برای هر بک‌اند (ایران‌ساین، PKI آن، API خود گروه)، و یک سرویس کوچک که فراخوانی‌های FIDO در SDK امضا را در خود می‌پیچد تا هیچ جای دیگری مستقیم به آن دست نزند.
  • صفحه‌ی وضعیت گواهی را ساختم - صفحه‌ای که کل اپ به آن آویزان است - و فرایند ابطال پشت آن را. ابطال گواهی، آن را هم در مرجع ثبت و هم در سرویس امضا باطل می‌کند و بعد اعتبارنامه را از گوشی حذف می‌کند؛ پس هیچ وضعیت نیمه‌باطلی باقی نمی‌ماند.
  • سطوح احراز هویت را در هر بازدید از سامانه‌های مرجع به دست می‌آوریم، نه از پیشرفتی که در اپ ذخیره شده باشد: سطح ۱ از شاهکار (تطبیق کد ملی با شماره موبایل)، سطح ۲ از پروفایل هویتی کاربر، سطح ۳ از نتیجه‌ی زنده‌سنجی - و وقتی گواهی معتبر وجود دارد، منقضی شدن زنده‌سنجی دیگر اهمیتی ندارد. کاربری که در میانه‌ی راه خارج می‌شود، به اولین سطح انجام‌نشده برمی‌گردد، نه به ابتدای کار.
  • صدور گواهی آن را به گوشی گره می‌زند. یک اعتبارنامه‌ی FIDO2 تازه با قفل چهره یا اثر انگشت دستگاه ساخته می‌شود و از جفت‌کلید محافظت می‌کند؛ هر اعتبارنامه‌ی قدیمی‌تر اول حذف می‌شود، و اگر صدور شکست بخورد اعتبارنامه‌ی جدید هم حذف می‌شود؛ پس تلاش دوباره همیشه از نقطه‌ای تمیز شروع می‌شود.
  • گواهی‌ای که روی سرور معتبر است ولی روی این گوشی اعتبارنامه‌ای ندارد، یک حالت مستقل است، نه یک خطا: صفحه می‌گوید گواهی روی گوشی صادرکننده است و دو راه را پیش می‌گذارد - ورود با همان گوشی، یا ابطال و صدور گواهی جدید.
  • ویدئوی زنده‌سنجی از جمله‌ای استفاده می‌کند که برای هر ضبط از نو از ایران‌ساین گرفته می‌شود و هم چهره و هم صدا در آن بررسی می‌شود؛ پس یک ضبط قابل تکرار نیست. ضبط، MP4 با H.264/AAC را ترجیح می‌دهد و به WebM برمی‌گردد، سافاری با وضوح و بیت‌ریت پایین‌تر ضبط می‌کند، و هر ویدئوی بیش از ۱۰ مگابایت پیش از ارسال متوقف می‌شود.
  • خطاهای دوربین و میکروفن دسته‌بندی می‌شوند - دسترسی رد شده، دستگاهی پیدا نشد، دستگاه مشغول است - و هرجا مرورگر پشتیبانی کند از طریق Permissions API پایش می‌شوند؛ پس هر خطا پیام خودش را دارد، نه یک پیام کلی.
  • مدارک هویتی مستقیم و با نمایش پیشرفت از طریق یک آدرس بارگذاری از پیش امضاشده به مخزن می‌روند و سپس تأیید می‌شوند؛ سقف ۱ مگابایت پیش از بارگذاری بررسی می‌شود، و دکمه‌ی ارسال تا رسیدن هر دو مدرک - کارت ملی و شناسنامه - غیرفعال می‌ماند.
  • ورود از طریق OIDC و SSO گروه انجام می‌شود، با پیام پایان نشست؛ توکن‌های یک نشست امضا فقط در حافظه نگه داشته می‌شوند، و داده‌های درخواست که پیش‌تر در localStorage نوشته می‌شدند از آن بیرون آمدند.

ویژگی‌های کلیدی

  • احراز هویت سه‌سطحی: کد ملی و موبایل، پروفایل هویتی، و زنده‌سنجی - عکس چهره، ویدئو با جمله‌ی تصادفی و تصویر کارت ملی و شناسنامه.
  • کلید امضا محافظت‌شده با یک اعتبارنامه‌ی FIDO2 / WebAuthn روی گوشی، که با چهره یا اثر انگشت باز می‌شود.
  • چرخه‌ی کامل گواهی: صدور، روزهای باقی‌مانده‌ی اعتبار، و ابطال هم در مرجع ثبت و هم در سرویس امضا.
  • ضبط ویدئو که در سافاری و کروم کار می‌کند: اول H.264/AAC، سپس WebM، وضوح و بیت‌ریت مخصوص سافاری، سقف ۱۰ مگابایت.
  • قراردادها درون اپ: فهرست بر اساس وضعیت (نیازمند امضا، امضاشده، منقضی‌شده)، پیش‌نمایش PDF، دانلود و امضا.
  • ورود یکپارچه با OIDC؛ توکن‌های نشست امضا هرگز در فضای ذخیره‌سازی مرورگر نوشته نمی‌شوند.

نتیجه

احراز هویت، صدور گواهی و ابطال از ابتدا تا انتها روی سرویس‌های واقعی اجرا می‌شوند، و امضای قرارداد - فهرست، پیش‌نمایش و امضای قراردادهای گروه - تازه‌ترین بخشی است که اضافه شده. چون پیشرفت از سامانه‌های مرجع خوانده می‌شود، خروج در میانه‌ی راه هزینه‌ای برای کاربر ندارد: از اولین سطح انجام‌نشده ادامه می‌دهد.

صفحه‌ها

برای دیدن هر صفحه در اندازه‌ی کامل، رویش بزنید.

پروژه‌های دیگر