تجربه ورود به سیستمی ایجاد کنید که از کلیدهای عبور استفاده کند و در عین حال کاربران رمز عبور موجود را در خود جای دهد.
کلیدهای عبور جایگزین گذرواژهها میشوند و حسابهای کاربری در وب را ایمنتر، سادهتر و استفاده آسانتر میکنند. با این حال، انتقال از احراز هویت مبتنی بر رمز عبور به احراز هویت مبتنی بر رمز عبور میتواند تجربه کاربر را پیچیده کند. استفاده از تکمیل خودکار فرم برای پیشنهاد کلیدهای عبور می تواند به ایجاد یک تجربه یکپارچه کمک کند.
چرا از تکمیل خودکار فرم برای ورود به سیستم با کلید عبور استفاده کنیم؟
با یک رمز عبور، کاربر می تواند تنها با استفاده از اثر انگشت، چهره یا پین دستگاه وارد یک وب سایت شود.
در حالت ایده آل، هیچ کاربر پسوردی وجود نخواهد داشت و جریان احراز هویت می تواند به سادگی یک دکمه ورود به سیستم باشد. وقتی کاربر روی دکمه ضربه میزند، یک گفتگوی انتخابگر حساب ظاهر میشود، کاربر میتواند حسابی را انتخاب کند، قفل صفحه را باز کند تا تأیید کند و وارد سیستم شود.
با این حال، انتقال از رمز عبور به احراز هویت مبتنی بر رمز عبور می تواند چالش برانگیز باشد. از آنجایی که کاربران به کلیدهای عبور تغییر می کنند، همچنان کسانی هستند که از رمز عبور استفاده می کنند و وب سایت ها باید هر دو نوع کاربر را در خود جای دهند. از خود کاربران نباید انتظار داشت که به خاطر بسپارند در کدام سایتها به کلیدهای عبور تغییر دادهاند، بنابراین درخواست از کاربران برای انتخاب روشی که از قبل استفاده کنند، UX ضعیفی خواهد بود.
کلیدهای عبور نیز یک فناوری جدید هستند. توضیح آنها و اطمینان از راحتی کاربران در استفاده از آنها می تواند یک چالش برای وب سایت ها باشد. برای حل هر دو مشکل میتوانیم به تجربیات کاربر آشنا برای تکمیل خودکار گذرواژهها اعتماد کنیم.
UI مشروط
برای ایجاد یک تجربه کاربری کارآمد برای کاربران رمز عبور و رمز عبور، میتوانید کلیدهای عبور را در پیشنهادات تکمیل خودکار قرار دهید. این رابط کاربری شرطی نامیده می شود و بخشی از استاندارد WebAuthn است.
به محض اینکه کاربر روی فیلد ورودی نام کاربری ضربه می زند، یک گفتگوی پیشنهاد تکمیل خودکار ظاهر می شود که کلیدهای عبور ذخیره شده را به همراه پیشنهادهای تکمیل خودکار رمز عبور برجسته می کند. سپس کاربر می تواند یک حساب کاربری انتخاب کند و از قفل صفحه دستگاه برای ورود به سیستم استفاده کند.
به این ترتیب، کاربران میتوانند با فرم موجود وارد وبسایت شما شوند، گویی چیزی تغییر نکرده است، اما در صورت داشتن یک رمز عبور، از مزایای امنیتی اضافهشده استفاده میکنند .
چگونه کار می کند
برای احراز هویت با یک رمز عبور، از WebAuthn API استفاده میکنید.
چهار مؤلفه در یک جریان تأیید هویت رمز عبور عبارتند از: کاربر:
- Backend : سرور باطن شما که پایگاه داده حساب ها را نگه می دارد و کلید عمومی و سایر ابرداده های مربوط به کلید عبور را ذخیره می کند.
- Frontend : نمای ظاهری شما که با مرورگر ارتباط برقرار می کند و درخواست های واکشی را به باطن ارسال می کند.
- مرورگر : مرورگر کاربر که جاوا اسکریپت شما را اجرا می کند.
- Authenticator : احراز هویت کاربر که کلید عبور را ایجاد و ذخیره می کند. این ممکن است در همان دستگاه مرورگر (به عنوان مثال هنگام استفاده از Windows Hello) یا در دستگاه دیگری مانند تلفن باشد.
- به محض اینکه کاربر در قسمت جلویی قرار می گیرد، از پشتیبان درخواست می کند تا با یک رمز عبور احراز هویت کند و
navigator.credentials.get()
را برای شروع احراز هویت با یک رمز عبور فراخوانی می کند. این یکPromise
برمی گرداند. - هنگامی که کاربر مکان نما را در قسمت ورود به سیستم قرار می دهد، مرورگر یک گفتگوی تکمیل خودکار رمز عبور شامل کلیدهای عبور را نمایش می دهد. اگر کاربر رمز عبور را انتخاب کند، یک گفتگوی احراز هویت ظاهر می شود.
- پس از اینکه کاربر هویت خود را با استفاده از قفل صفحه دستگاه تأیید کرد، وعده حل میشود و اعتبار کلید عمومی به صفحه نمایش بازگردانده میشود.
- فرانت اند اعتبار کلید عمومی را به باطن ارسال می کند. Backend امضا را در برابر کلید عمومی حساب منطبق در پایگاه داده تأیید می کند. در صورت موفقیت آمیز بودن، کاربر وارد سیستم می شود.
با یک کلید عبور از طریق تکمیل خودکار فرم احراز هویت کنید
هنگامی که کاربری میخواهد وارد سیستم شود، میتوانید یک تماس مشروط WebAuthn get
تا نشان دهید که کلیدهای عبور ممکن است در پیشنهادهای تکمیل خودکار گنجانده شوند. یک تماس مشروط به WebAuthn 's navigator.credentials.get()
UI را نشان نمی دهد و تا زمانی که کاربر حسابی را برای ورود به سیستم از پیشنهادات تکمیل خودکار انتخاب کند، در حالت تعلیق باقی می ماند. اگر کاربر یک رمز عبور را انتخاب کند، مرورگر به جای پر کردن فرم ورود، این قول را با یک اعتبارنامه حل می کند. سپس مسئولیت ورود کاربر بر عهده صفحه است.
قسمت ورودی فرم را حاشیه نویسی کنید
در صورت نیاز، یک ویژگی autocomplete
به قسمت input
نام کاربری اضافه کنید. username
و webauthn
به عنوان نشانه های آن اضافه کنید تا به آن اجازه دهید کلیدهای عبور را پیشنهاد دهد.
<input type="text" name="username" autocomplete="username webauthn" ...>
تشخیص ویژگی
قبل از فراخوانی یک تماس API شرطی WebAuthn، بررسی کنید که آیا:
- مرورگر از WebAuthn با
PublicKeyCredential
پشتیبانی می کند.
- مرورگر از UI شرطی WebAuthn با
PublicKeyCredenital.isConditionalMediationAvailable()
پشتیبانی می کند.
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if conditional mediation is available.
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
if (isCMA) {
// Call WebAuthn authentication
}
}
چالشی را از سرور RP دریافت کنید
چالشی را از سرور RP که برای فراخوانی navigator.credentials.get()
لازم است واکشی کنید:
-
challenge
: یک چالش ایجاد شده توسط سرور در یک ArrayBuffer. این برای جلوگیری از حملات تکراری لازم است. اطمینان حاصل کنید که در هر تلاش برای ورود به سیستم یک چالش جدید ایجاد میکنید و پس از مدت زمان معینی یا پس از عدم تأیید اعتبار تلاش برای ورود به سیستم، آن را نادیده میگیرید. آن را مانند یک توکن CSRF در نظر بگیرید. -
allowCredentials
: آرایه ای از اعتبارنامه های قابل قبول برای این احراز هویت. یک آرایه خالی را ارسال کنید تا به کاربر اجازه دهید یک رمز عبور موجود را از لیست نشان داده شده توسط مرورگر انتخاب کند. userVerification
: نشان می دهد که آیا تأیید کاربر با استفاده از قفل صفحه دستگاه"required"
،"preferred"
یا"discouraged"
است. پیشفرض"preferred"
است، به این معنی که احراز هویت ممکن است تأیید کاربر را رد کند. این را روی"preferred"
تنظیم کنید یا ویژگی را حذف کنید.
برای احراز هویت کاربر، WebAuthn API را با پرچم conditional
فراخوانی کنید
برای شروع انتظار برای احراز هویت کاربر navigator.credentials.get()
فراخوانی کنید.
// To abort a WebAuthn call, instantiate an `AbortController`.
const abortController = new AbortController();
const publicKeyCredentialRequestOptions = {
// Server generated challenge
challenge: ****,
// The same RP ID as used during registration
rpId: 'example.com',
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
-
rpId
: شناسه RP یک دامنه است و یک وب سایت می تواند دامنه یا پسوند قابل ثبت خود را مشخص کند. این مقدار باید با rp.id استفاده شده در هنگام ایجاد رمز عبور مطابقت داشته باشد.
به خاطر داشته باشید که mediation: 'conditional'
تا درخواست را مشروط کنید.
اعتبار کلید عمومی بازگشتی را به سرور RP ارسال کنید
پس از اینکه کاربر یک حساب را انتخاب کرد و با استفاده از قفل صفحه دستگاه موافقت کرد، وعده بازگشت یک شی PublicKeyCredential
به جلوی RP حل می شود.
یک قول به دلایل مختلف قابل رد است. بسته به ویژگی name
شی Error
، باید خطاها را بر این اساس مدیریت کنید:
-
NotAllowedError
: کاربر عملیات را لغو کرده است. - استثناهای دیگر : اتفاق غیرمنتظره ای رخ داد. مرورگر یک گفتگوی خطا را به کاربر نشان می دهد.
شی اعتبار کلید عمومی حاوی ویژگی های زیر است:
-
id
: شناسه رمزگذاری شده در base64url اعتبار کلید عبور تأیید شده. -
rawId
: یک نسخه ArrayBuffer از شناسه اعتبار. -
response.clientDataJSON
: یک ArrayBuffer از داده های مشتری. این فیلد حاوی اطلاعاتی مانند چالش و مبدأ است که سرور RP باید تأیید کند. -
response.authenticatorData
: یک ArrayBuffer از داده های authenticator. این فیلد حاوی اطلاعاتی مانند شناسه RP است. -
response.signature
: یک ArrayBuffer از امضا. این مقدار هسته اعتبارنامه است و باید در سرور تأیید شود. -
response.userHandle
: یک ArrayBuffer که حاوی شناسه کاربری است که در زمان ایجاد تنظیم شده است. این مقدار را می توان به جای شناسه اعتبار استفاده کرد، اگر سرور باید مقادیر شناسه ای را که استفاده می کند انتخاب کند، یا اگر پشتیبان بخواهد از ایجاد نمایه در شناسه های اعتبار خودداری کند. -
authenticatorAttachment
: زمانی که این اعتبار از دستگاه محلی آمده است،platform
برمیگرداند. در غیر این صورتcross-platform
، به ویژه زمانی که کاربر از تلفن برای ورود به سیستم استفاده میکند . اگر کاربر نیاز به استفاده از تلفن برای ورود به سیستم داشت، از او بخواهید یک کلید عبور در دستگاه محلی ایجاد کند . -
type
: این فیلد همیشه روی"public-key"
تنظیم می شود.
اگر از یک کتابخانه برای مدیریت شی اعتبار کلید عمومی در سرور RP استفاده می کنید، توصیه می کنیم پس از کدگذاری جزئی با base64url، کل شی را به سرور ارسال کنید.
امضا را تایید کنید
هنگامی که اعتبار کلید عمومی را در سرور دریافت کردید، آن را به کتابخانه FIDO ارسال کنید تا شی مورد نظر پردازش شود.
شناسه اعتبار مطابق با ویژگی id
را جستجو کنید (اگر نیاز به تعیین حساب کاربری دارید، از ویژگی userHandle
استفاده کنید که همان user.id
است که هنگام ایجاد اعتبار مشخص کرده اید). ببینید آیا می توان signature
اعتبارنامه را با کلید عمومی ذخیره شده تأیید کرد. برای انجام این کار، توصیه می کنیم به جای نوشتن کد خود از یک کتابخانه سمت سرور یا یک راه حل استفاده کنید. میتوانید کتابخانههای منبع باز را در مخزن گیتهاب awesome-webauth بیابید .
هنگامی که اعتبار با یک کلید عمومی منطبق تأیید شد، کاربر را وارد کنید.
دستورالعمل های دقیق تر را در تأیید هویت رمز عبور سمت سرور دنبال کنید