Чем будешь пользоваться для выполнения запросов нескольких Promise?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как подтверждается безопасность данных?
Безопасность данных — одна из ключевых ответственностей фронтенд-разработчика. На клиентской стороне существует несколько стратегий для защиты информации пользователя и предотвращения атак.
1. HTTPS и Шифрование
Первая линия защиты — всегда использовать HTTPS вместо HTTP. Это обеспечивает шифрование данных при передаче.
// Плохо: HTTP не защифрован
fetch("http://api.example.com/user/data");
// Хорошо: HTTPS зашифрован
fetch("https://api.example.com/user/data");
// Принудить HTTPS в Next.js
// next.config.js
module.exports = {
redirects: async () => {
return [
{
source: "/:path*",
has: [{ type: "header", key: "x-forwarded-proto", value: "http" }],
destination: "https://:host/:path*",
permanent: false,
},
];
},
};
2. Аутентификация и Токены
Правильная работа с токенами критична для безопасности.
// Хранение токена в httpOnly cookie (безопаснее, чем localStorage)
// Серверная часть устанавливает:
// Set-Cookie: token=xxx; HttpOnly; Secure; SameSite=Strict
// Клиентская часть автоматически отправляет с каждым запросом
fetch("https://api.example.com/protected", {
method: "GET",
credentials: "include", // Отправить cookies
});
// Если нужно хранить в памяти (не localStorage):
let authToken = null; // Теряется при перезагрузке, но безопаснее
function login(credentials) {
return fetch("https://api.example.com/login", {
method: "POST",
body: JSON.stringify(credentials),
}).then((res) => res.json()
.then((data) => {
authToken = data.token;
return data;
})
);
}
function makeAuthenticatedRequest(url) {
return fetch(url, {
headers: {
"Authorization": `Bearer ${authToken}`,
},
});
}
3. Защита от XSS (Cross-Site Scripting)
XSS — атака, при которой вредоносный скрипт вставляется в страницу. React защищает от этого автоматически, но нужна осторожность.
// Плохо: dangerouslySetInnerHTML позволяет XSS
function UserComment({ comment }) {
return (
<div dangerouslySetInnerHTML={{ __html: comment.text }} />
);
}
// Хорошо: React автоматически экранирует текст
function UserComment({ comment }) {
return <div>{comment.text}</div>;
}
// Если действительно нужно отобразить HTML, используй библиотеку
import DOMPurify from "dompurify";
function SafeHTML({ html }) {
const cleanHTML = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
}
4. CSRF (Cross-Site Request Forgery) защита
CSRF-токены предотвращают запросы от вредоносных сайтов.
// Сервер генерирует CSRF токен
fetch("https://api.example.com/csrf-token")
.then((res) => res.json())
.then((data) => {
const csrfToken = data.token;
// Отправляем с каждым изменяющим запросом
return fetch("https://api.example.com/user/update", {
method: "POST",
headers: {
"X-CSRF-Token": csrfToken,
},
body: JSON.stringify({ name: "John" }),
});
});
5. Валидация Входных Данных
Никогда не доверяй пользовательскому вводу.
import { z } from "zod";
// Схема валидации
const UserSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
age: z.number().min(0).max(150),
});
function SignupForm() {
const [data, setData] = useState({ email: "", password: "", age: "" });
const [errors, setErrors] = useState({});
const handleSubmit = async (e) => {
e.preventDefault();
try {
const validated = UserSchema.parse(data);
await fetch("https://api.example.com/signup", {
method: "POST",
body: JSON.stringify(validated),
});
} catch (err) {
if (err instanceof z.ZodError) {
setErrors(err.flatten().fieldErrors);
}
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={data.email}
onChange={(e) => setData({ ...data, email: e.target.value })}
/>
{errors.email && <span>{errors.email[0]}</span>}
</form>
);
}
6. Content Security Policy (CSP)
CSP предотвращает загрузку вредоносного содержимого.
// next.config.js
module.exports = {
async headers() {
return [
{
source: "/(.*)",
headers: [
{
key: "Content-Security-Policy",
value: "default-src self; script-src self unsafe-inline; style-src self unsafe-inline",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "X-Frame-Options",
value: "DENY",
},
],
},
];
},
};
7. Environment Variables
Никогда не коммит секреты в репозиторий.
// .env.local (в .gitignore)
REACT_APP_API_KEY=secret123
REACT_APP_API_URL=https://api.example.com
// Используй в коде
const apiUrl = process.env.REACT_APP_API_URL;
const apiKey = process.env.REACT_APP_API_KEY;
// Плохо: хардкод
const token = "my-secret-token-123"; // НИКОГДА
8. Санитизация URL
function safeRedirect(url) {
try {
const parsed = new URL(url);
// Разреши редирект только на твой домен
if (parsed.origin === window.location.origin) {
window.location.href = url;
}
} catch (err) {
console.error("Invalid URL", err);
}
}
Чеклист безопасности
- Используется HTTPS везде
- Токены хранятся в httpOnly cookies
- Не используется localStorage для чувствительных данных
- React автоматически экранирует текст
- Валидируется пользовательский ввод
- Используется CSP header
- Секреты в .env, не в коде
- Регулярно обновляются зависимости
- Используется HTTPS везде, включая API запросы
Безопасность — это постоянный процесс, требующий постоянного внимания и обновления знаний.