Виправлення помилок.
Додан новий метод авторізації в застосунок.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Serverless FaceID Test</title>
|
||||
<style>
|
||||
body { font-family: -apple-system, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; background-color: #f5f5f7; }
|
||||
.card { background: white; padding: 30px; border-radius: 20px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); text-align: center; max-width: 320px; width: 100%; }
|
||||
button { background: #0071e3; color: white; border: none; padding: 14px; font-size: 16px; border-radius: 12px; cursor: pointer; margin: 10px 0; width: 100%; font-weight: 500; }
|
||||
button.secondary { background: #34c759; }
|
||||
#status { margin-top: 20px; font-size: 14px; color: #86868b; word-break: break-word; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="card">
|
||||
<h2>Безсерверный тест</h2>
|
||||
<p>Проверка вызова Face ID на клиенте</p>
|
||||
<button id="testFaceIdBtn">Вызвать Face ID</button>
|
||||
<div id="status">Нажмите кнопку для теста</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Нам нужен фейковый challenge в виде ArrayBuffer (минимум 16 байт)
|
||||
const fakeChallenge = new Uint8Array([
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
|
||||
]).buffer;
|
||||
|
||||
// Фейковый ID пользователя (тоже ArrayBuffer)
|
||||
const fakeUserId = new Uint8Array([
|
||||
99, 98, 97, 96, 95, 94, 93, 92
|
||||
]).buffer;
|
||||
|
||||
const log = (msg, isErr = false) => {
|
||||
const el = document.getElementById('status');
|
||||
el.innerText = msg;
|
||||
el.style.color = isErr ? '#ff3b30' : '#1d1d1f';
|
||||
};
|
||||
|
||||
document.getElementById('testFaceIdBtn').addEventListener('click', async () => {
|
||||
log('Инициализация API...');
|
||||
|
||||
// 1. Проверяем, поддерживает ли вообще браузер/устройство биометрию
|
||||
if (!window.PublicKeyCredential) {
|
||||
log('WebAuthn не поддерживается в этом браузере.', true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
log('Вызов сканера Face ID...');
|
||||
|
||||
// 2. Конфигурируем запрос к системе
|
||||
const publicKeyCredentialCreationOptions = {
|
||||
challenge: fakeChallenge,
|
||||
rp: {
|
||||
name: "Local Test PWA",
|
||||
id: window.location.hostname // Автоматически подставит localhost или ваш домен
|
||||
},
|
||||
user: {
|
||||
id: fakeUserId,
|
||||
name: "[email protected]",
|
||||
displayName: "Тестовый Пользователь"
|
||||
},
|
||||
pubKeyCredParams: [
|
||||
{ type: "public-key", alg: -7 } // Алгоритм ES256, стандартный для Apple устройств
|
||||
],
|
||||
authenticatorSelection: {
|
||||
authenticatorAttachment: "platform", // Заставляет iOS использовать именно встроенную биометрию
|
||||
userVerification: "required" // Требует успешного сканирования (FaceID/TouchID/Пин-код)
|
||||
},
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
// 3. Триггерим нативное окно iOS
|
||||
const credential = await navigator.credentials.create({
|
||||
publicKey: publicKeyCredentialCreationOptions
|
||||
});
|
||||
|
||||
// Если промис успешно разрешился — Face ID отработал, данные получены
|
||||
console.log('Успешный ответ от Face ID:', credential);
|
||||
log('🎉 Успех! Нативное окно Face ID открылось и успешно подтвердило личность.');
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// Если пользователь нажал "Отмена" в шторке Face ID, сработает NotAllowedError
|
||||
if (err.name === 'NotAllowedError') {
|
||||
log('Действие отменено пользователем или таймаут.', true);
|
||||
} else {
|
||||
log('Ошибка: ' + err.message, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user