آخرین به‌روزرسانی‌های API مدیریت اعتبار

برخی از به‌روزرسانی‌هایی که در اینجا توضیح داده شده‌اند، در جلسه Google I/O توضیح داده شده‌اند، ورود امن و بدون درز: نگه داشتن کاربران درگیر :

کروم 57

Chrome 57 این تغییر مهم را در Credential Management API معرفی کرد.

اعتبارنامه ها را می توان از یک زیر دامنه متفاوت به اشتراک گذاشت

Chrome اکنون می‌تواند با استفاده از Credential Management API یک اعتبار ذخیره شده در یک زیر دامنه متفاوت را بازیابی کند. برای مثال، اگر یک رمز عبور در login.example.com ذخیره شده باشد، یک اسکریپت در www.example.com می تواند آن را به عنوان یکی از موارد حساب در گفتگوی انتخابگر حساب نشان دهد.

شما باید صراحتاً رمز عبور را با استفاده از navigator.credentials.store() ذخیره کنید، به طوری که وقتی کاربر یک اعتبار را با ضربه زدن بر روی کادر محاوره ای انتخاب می کند، رمز عبور داده می شود و در مبدا فعلی کپی می شود.

پس از ذخیره شدن، رمز عبور به عنوان یک اعتبار در همان مبدا www.example.com به بعد در دسترس است.

در تصویر زیر، اطلاعات اعتبار ذخیره شده در login.aliexpress.com برای m.aliexpress.com قابل مشاهده است و برای انتخاب کاربر در دسترس است:

انتخابگر حساب که جزئیات ورود به زیر دامنه انتخاب شده را نشان می دهد

کروم 60

Chrome 60 چندین تغییر مهم را در Credential Management API معرفی می کند:

تشخیص ویژگی نیاز به توجه دارد

برای اینکه ببینید آیا Credential Management API برای دسترسی به اعتبارنامه‌های مبتنی بر رمز عبور و اعتبارنامه‌های فدرال در دسترس است، بررسی کنید window.PasswordCredential یا window.FederatedCredential در دسترس است.

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

اکنون شی PasswordCredential شامل رمز عبور است

Credential Management API رویکرد محافظه‌کارانه‌ای برای مدیریت گذرواژه‌ها داشت. این گذرواژه‌ها را از جاوا اسکریپت مخفی می‌کرد و از توسعه‌دهندگان می‌خواست که شی PasswordCredential را مستقیماً برای اعتبارسنجی از طریق یک افزونه به API fetch() به سرور خود ارسال کنند.

اما این رویکرد تعدادی محدودیت را ایجاد کرد. ما بازخورد دریافت کردیم مبنی بر اینکه توسعه دهندگان نمی توانند از API استفاده کنند زیرا:

  • آنها باید رمز عبور را به عنوان بخشی از یک شی JSON ارسال می کردند.

  • آنها باید مقدار هش رمز عبور را به سرور خود ارسال می کردند.

پس از انجام یک تجزیه و تحلیل امنیتی و تشخیص اینکه پنهان کردن رمزهای عبور از جاوا اسکریپت مانع از همه بردارهای حمله به اندازه ای که انتظار داشتیم نمی شود، تصمیم گرفتیم تغییری ایجاد کنیم.

Credential Management API اکنون شامل یک رمز عبور خام در یک شی اعتبار بازگردانده شده است، بنابراین شما به عنوان متن ساده به آن دسترسی دارید. می توانید از روش های موجود برای تحویل اطلاعات اعتبار به سرور خود استفاده کنید:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

واکشی سفارشی به زودی منسوخ خواهد شد

برای تعیین اینکه آیا از یک تابع fetch() سفارشی استفاده می کنید، بررسی کنید که آیا از یک شی PasswordCredential یا یک شی FederatedCredential به عنوان مقدار credentials استفاده می کند، به عنوان مثال:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

استفاده از تابع fetch() معمولی همانطور که در مثال کد قبلی نشان داده شده است یا استفاده از XMLHttpRequest توصیه می شود.

تا Chrome 60، navigator.credentials.get() یک ویژگی اختیاری unmediated را با یک پرچم بولی می پذیرفت. به عنوان مثال:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

تنظیم unmediated: true از نشان دادن انتخابگر حساب هنگام ارسال اعتبار توسط مرورگر جلوگیری می کند.

پرچم اکنون به عنوان میانجی گسترش یافته است. میانجیگری کاربر ممکن است زمانی اتفاق بیفتد که:

  • کاربر باید حسابی را برای ورود به سیستم انتخاب کند.

  • کاربر می‌خواهد پس از تماس navigator.credentials.requireUseMediation() به طور واضح وارد سیستم شود.

یکی از گزینه های زیر را برای مقدار mediation انتخاب کنید:

ارزش mediation در مقایسه با پرچم بولی رفتار
silent برابر unmediated: true اعتبار بدون نشان دادن انتخابگر حساب منتقل شد.
optional برابر است unmediated: false اگر قبلاً preventSilentAccess() فراخوانی شده باشد، یک انتخابگر حساب را نشان می دهد.
required یک گزینه جدید همیشه یک انتخابگر حساب نشان داده شود. زمانی مفید است که می‌خواهید به کاربر اجازه دهید با استفاده از گفتگوی انتخابگر حساب بومی، حسابی را تغییر دهد.

در این مثال، اعتبار بدون نشان دادن یک انتخابگر حساب، معادل پرچم قبلی، unmediated: true :

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

requireUserMediation() تغییر نام داد تا به preventSilentAccess()

برای هماهنگی مناسب با ویژگی mediation جدید ارائه شده در فراخوانی get() ، متد navigator.credentials.requireUserMediation() به navigator.credentials.preventSilentAccess() تغییر نام داده است.

روش تغییر نام داده شده از ارسال اعتبار بدون نشان دادن انتخابگر حساب جلوگیری می کند (گاهی اوقات بدون واسطه کاربر نامیده می شود). این زمانی مفید است که کاربر از یک وب‌سایت خارج شود یا از یک وب‌سایت لغو ثبت نام کند و نمی‌خواهد در بازدید بعدی به‌طور خودکار به سیستم وارد شود.

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

با متد جدید navigator.credentials.create()

اکنون می توانید با متد جدید navigator.credentials.create() ، اشیاء اعتبار را به صورت ناهمزمان ایجاد کنید. برای مقایسه بین هر دو رویکرد همگام سازی و همگام سازی به ادامه مطلب مراجعه کنید.

ایجاد یک شی PasswordCredential

رویکرد همگام سازی
let c = new PasswordCredential(form);
رویکرد Async (جدید)
let c = await navigator.credentials.create({
    password: form
});

یا:

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

ایجاد یک شی FederatedCredential

رویکرد همگام سازی
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
رویکرد Async (جدید)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

راهنمای مهاجرت

آیا اجرای موجودی از Credential Management API دارید؟ ما یک سند راهنمای مهاجرت داریم که می توانید برای ارتقا به نسخه جدید آن را دنبال کنید.