Интерфейс пользователя для MFA
Экран подтверждения MFA — это простой, но важный компонент. Он должен быть интуитивно понятным и минималистичным, чтобы пользователь не запутался, пытаясь ввести код. Основные элементы интерфейса:
- Поле для ввода временного кода (обычно ограничено 6 цифрами).
- Кнопка для подтверждения кода.
- Сообщение об ошибке (на случай неправильного ввода кода).
- Ссылка для повторной отправки кода, если пользователь его не получил.
Представьте, что мы работаем над приложением, где после успешной авторизации пользователь направляется на экран ввода MFA-кода. Вот пример базовой структуры нашего компонента:
import React, { useState } from "react";
interface MFAProps {
onVerifyCode: (code: string) => void;
onResendCode: () => void;
}
const MFA: React.FC<MFAProps> = ({ onVerifyCode, onResendCode }) => {
const [code, setCode] = useState("");
const [error, setError] = useState("");
const handleSubmit = () => {
if (code.length !== 6) {
setError("Код должен содержать 6 цифр.");
return;
}
onVerifyCode(code);
};
return (
<div style={{ padding: "20px", maxWidth: "400px", margin: "auto" }}>
<h2>Введите код подтверждения</h2>
<input
type="text"
value={code}
onChange={(e) => setCode(e.target.value)}
maxLength={6}
placeholder="6-значный код"
style={{ width: "100%", padding: "10px", marginBottom: "20px" }}
/>
{error && <p style={{ color: "red" }}>{error}</p>}
<button onClick={handleSubmit} style={{ width: "100%", padding: "10px" }}>
Подтвердить
</button>
<p>
Не получили код?{" "}
<button onClick={onResendCode} style={{ color: "blue", border: "none", background: "none", cursor: "pointer" }}>
Отправить повторно
</button>
</p>
</div>
);
};
export default MFA;
Паттерны UX для улучшения взаимодействия
- Обязательное ограничение длины кода. Во входном поле используется
maxLength, чтобы пользователь не мог ввести больше символов, чем нужно. - Автоматический фокус на поле ввода. Это улучшает UX, так как пользователь может сразу начать вводить код без необходимости кликать в поле.
- Чёткие сообщения об ошибках. Например: "Код должен содержать 6 цифр" или "Неверный код, попробуйте ещё раз."
Подключение компонента к основному приложению
Для работы с MFA-компонентом нам нужно передать функции onVerifyCode и onResendCode. Они будут отвечать за проверку кода и повторную отправку соответственно:
const handleVerifyCode = (code: string) => {
console.log("Проверяем код:", code);
// Здесь будет логика проверки кода
};
const handleResendCode = () => {
console.log("Повторная отправка кода");
// Здесь будет API-запрос для повторной отправки кода
};
<MFA onVerifyCode={handleVerifyCode} onResendCode={handleResendCode} />;
Управление процессом аутентификации
Теперь, когда у нас есть интерфейс для MFA, давайте разберём, как управлять состоянием и процессом аутентификации.
Управление состоянием MFA в приложении
Состояние MFA можно хранить либо на глобальном уровне (например, с помощью Redux), либо локально в компонентах. Для простоты мы будем использовать контекст и хук useState.
Создадим контекст для управления состоянием:
import React, { createContext, useContext, useState } from "react";
// Типизация состояния MFA
interface MFAContextValue {
isMFAEnabled: boolean;
isMFAVerified: boolean;
setMFAVerified: (status: boolean) => void;
}
const MFAContext = createContext<MFAContextValue | undefined>(undefined);
export const MFAProvider: React.FC = ({ children }) => {
const [isMFAEnabled, setIsMFAEnabled] = useState(true); // MFA включена
const [isMFAVerified, setMFAVerified] = useState(false); // MFA ещё не пройдена
return (
<MFAContext.Provider value={{ isMFAEnabled, isMFAVerified, setMFAVerified }}>
{children}
</MFAContext.Provider>
);
};
export const useMFA = () => {
const context = useContext(MFAContext);
if (!context) {
throw new Error("useMFA должен использоваться внутри MFAProvider");
}
return context;
};
Использование состояния в компонентах
Теперь мы можем подключить состояние MFA к нашему приложению:
import { useMFA } from "./MFAProvider";
const App: React.FC = () => {
const { isMFAEnabled, isMFAVerified, setMFAVerified } = useMFA();
const handleVerifyCode = (code: string) => {
// Здесь подразумевается проверка (например, запрос на сервер)
if (code === "123456") {
console.log("Код подтверждён");
setMFAVerified(true);
} else {
console.error("Неверный код");
}
};
return (
<div>
{isMFAEnabled && !isMFAVerified ? (
<MFA onVerifyCode={handleVerifyCode} onResendCode={() => console.log("Повторная отправка")} />
) : (
<h1>Добро пожаловать в приложение!</h1>
)}
</div>
);
};
Интеграция с API
Для обработки API-запросов мы можем создать отдельный сервис:
export const verifyMFACode = async (code: string): Promise<boolean> => {
// Пример запроса на сервер для проверки кода
const response = await fetch("/api/mfa/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code }),
});
if (!response.ok) {
throw new Error("Ошибка подтверждения кода");
}
const data = await response.json();
return data.success; // Предполагаем, что сервер возвращает { success: true/false }
};
И используем его в функции handleVerifyCode:
const handleVerifyCode = async (code: string) => {
try {
const success = await verifyMFACode(code);
if (success) {
setMFAVerified(true);
} else {
console.error("Неверный код");
}
} catch (error) {
console.error(error.message);
}
};
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ