Типы аутентификации
▸Cookie-based сессии
Сервер создаёт сессию и хранит ID в cookie. Клиент отправляет cookie при каждом запросе.
▸Token-based (JWT)
Сервер создаёт токен с данными пользователя. Клиент хранит токен и отправляет в заголовке.
▸OAuth 2.0
Позволяет аутентифицироваться через сторонние сервисы (Google, GitHub).
Сессии
▸Express сессии
1npm install express-session
1import session from 'express-session';23app.use(session({4 secret: 'your-secret-key',5 resave: false,6 saveUninitialized: false,7 cookie: {8 secure: true,9 httpOnly: true,10 maxAge: 24 * 60 * 60 * 1000,11 },12}));
▸MongoDB для сессий
1npm install connect-mongo
1import MongoStore from 'connect-mongo';23app.use(session({4 store: MongoStore.create({5 mongoUrl: 'mongodb://localhost:27017/myapp',6 collectionName: 'sessions',7 }),8 secret: 'your-secret',9 resave: false,10 saveUninitialized: false,11}));
JWT (JSON Web Tokens)
▸Структура JWT
JWT состоит из трёх частей: header.payload.signature
▸Создание токена
1npm install jsonwebtoken
1import jwt from 'jsonwebtoken';23const token = jwt.sign(4 { userId: user.id, email: user.email },5 process.env.JWT_SECRET,6 { expiresIn: '24h' }7);
▸Верификация токена
1function authenticateToken(req, res, next) {2 const authHeader = req.headers['authorization'];3 const token = authHeader && authHeader.split(' ')[1];45 if (!token) return res.sendStatus(401);67 jwt.verify(token, process.env.JWT_SECRET, (err, user) => {8 if (err) return res.sendStatus(403);9 req.user = user;10 next();11 });12}
▸Refresh tokens
1const accessToken = jwt.sign(2 { userId: user.id },3 process.env.JWT_SECRET,4 { expiresIn: '15m' }5);67const refreshToken = jwt.sign(8 { userId: user.id },9 process.env.JWT_REFRESH_SECRET,10 { expiresIn: '7d' }11);
OAuth 2.0
▸Google OAuth
1npm install passport passport-google-oauth20
1import passport from 'passport';2import { Strategy as GoogleStrategy } from 'passport-google-oauth20';34passport.use(new GoogleStrategy({5 clientID: process.env.GOOGLE_CLIENT_ID,6 clientSecret: process.env.GOOGLE_CLIENT_SECRET,7 callbackURL: '/auth/google/callback',8}, (accessToken, refreshToken, profile, done) => {9 // Найти или создать пользователя10 User.findOrCreate({ googleId: profile.id }, (err, user) => {11 return done(err, user);12 });13}));
▸GitHub OAuth
1import { Strategy as GitHubStrategy } from 'passport-github2';23passport.use(new GitHubStrategy({4 clientID: process.env.GITHUB_CLIENT_ID,5 clientSecret: process.env.GITHUB_CLIENT_SECRET,6 callbackURL: '/auth/github/callback',7}, (accessToken, refreshToken, profile, done) => {8 // обработка профиля9}));
Хеширование паролей
▸bcrypt
1npm install bcrypt
1import bcrypt from 'bcrypt';23// Хеширование4const hashedPassword = await bcrypt.hash(password, 10);56// Верификация7const isValid = await bcrypt.compare(password, hashedPassword);
Безопасность
▸CSRF защита
1npm install csurf
1import csurf from 'csurf';23app.use(csurf({ cookie: true }));
▸Rate limiting
1npm install express-rate-limit
1import rateLimit from 'express-rate-limit';23const limiter = rateLimit({4 windowMs: 15 * 60 * 1000,5 max: 100,6 message: 'Слишком много запросов',7});89app.use('/api/', limiter);
▸Helmet
1npm install helmet
1import helmet from 'helmet';23app.use(helmet());
Best Practices
▸Не храните пароли в открытом виде
Всегда хешируйте пароли bcrypt'ом с солью.
▸Используйте HTTPS
Все запросы должны быть через HTTPS.
▸Валидируйте входные данные
Используйте Joi, Zod или Yup для валидации.
▸Не раскрывайте информацию об ошибках
В продакшене не показывайте детали ошибок.
Заключение
Аутентификация — критически важная часть приложения. Используйте JWT для stateless API, сессии для server-rendered приложений и OAuth для входа через соцсети. Всегда следуйте best practices безопасности.