Введение
Представьте, что вы обустраиваете квартиру (ваше красивое React-приложение). Логин и регистрация — это ваш домофон. Без них любой человек может заскочить в гости (или взломать). Механизм авторизации гарантирует, что только зарегистрированные пользователи смогут зайти, а логин позволяет "напомнить" нам, кто они такие.
Что мы будем делать?
Наша цель — реализовать следующие шаги:
- Создать форму для логина.
- Создать форму для регистрации.
- Отправлять данные на сервер и получать JWT.
- Сохранять полученный токен и использовать его для дальнейших запросов.
Практическая реализация
1. Создание формы логина
Для начала нам нужно создать компонент для логина. Он будет содержать два поля: email и password. Используем useState и TypeScript для типизации.
import React, { useState } from 'react';
interface LoginFormProps {
onLogin: (email: string, password: string) => void;
}
const LoginForm: React.FC<LoginFormProps> = ({ onLogin }) => {
const [email, setEmail] = useState<string>('');
const [password, setPassword] = useState<string>('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onLogin(email, password);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<button type="submit">Login</button>
</form>
);
};
export default LoginForm;
- Здесь мы используем
onLoginкак пропс, чтобы передавать логин-данные в родительский компонент. - Сохраняем состояние ввода в локальный
useState.
2. Создание формы регистрации
Регистрация почти такая же, как логин, только добавим дополнительное поле для подтверждения пароля.
interface RegisterFormProps {
onRegister: (email: string, password: string) => void;
}
const RegisterForm: React.FC<RegisterFormProps> = ({ onRegister }) => {
const [email, setEmail] = useState<string>('');
const [password, setPassword] = useState<string>('');
const [confirmPassword, setConfirmPassword] = useState<string>('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (password !== confirmPassword) {
alert('Passwords do not match!');
return;
}
onRegister(email, password);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<div>
<label>Confirm Password:</label>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
</div>
<button type="submit">Register</button>
</form>
);
};
export default RegisterForm;
Обратите внимание на проверку совпадения паролей. Это минимальная валидация на клиенте.
3. Настройка AuthService
Теперь сделаем модуль для работы с сервером. Воспользуемся библиотекой Axios для отправки запросов.
Убедитесь, что вы её установили:
npm install axios
import axios from 'axios';
const API_URL = 'http://localhost:5000/api/auth'; // Ваш сервер
export const login = async (email: string, password: string) => {
const response = await axios.post(`${API_URL}/login`, { email, password });
return response.data; // Сервер должен возвращать JWT
};
export const register = async (email: string, password: string) => {
const response = await axios.post(`${API_URL}/register`, { email, password });
return response.data;
};
Здесь login и register отправляют данные и возвращают результат. Ответ должен содержать JWT.
4. Интеграция с React-приложением
Теперь мы объединим наши формы с AuthService и реализуем обработку логина и регистрации.
import React from 'react';
import LoginForm from './LoginForm';
import RegisterForm from './RegisterForm';
import { login, register } from './AuthService';
const App: React.FC = () => {
const handleLogin = async (email: string, password: string) => {
try {
const data = await login(email, password);
localStorage.setItem('token', data.token); // Сохраняем JWT.
alert('Logged in successfully!');
} catch (error) {
alert('Login failed!');
}
};
const handleRegister = async (email: string, password: string) => {
try {
const data = await register(email, password);
alert('Registered successfully! Now you can log in.');
} catch (error) {
alert('Registration failed!');
}
};
return (
<div>
<h1>Login</h1>
<LoginForm onLogin={handleLogin} />
<h1>Register</h1>
<RegisterForm onRegister={handleRegister} />
</div>
);
};
export default App;
Где:
localStorage.setItem('token', data.token)сохраняет токен вlocalStorage.- Обрабатываем ошибки, возвращаемые сервером.
Предостережения и типичные ошибки
Сохранение пароля в localStorage? Пожалуйста, не делайте этого! Пользователи вас не простят. Сохранять нужно только JWT, а пароли передавать через HTTPS.
Ещё одна ошибка — игнорирование ошибок сервера. Обрабатывайте их. Если сервер вернул 401 (Unauthorized) — покажите пользователю ошибку.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ