JavaRush /Курсы /Модуль 2: Fullstack /Безопасность и управление доступом

Безопасность и управление доступом

Модуль 2: Fullstack
18 уровень , 5 лекция
Открыта

6.1 Аутентификация и авторизация пользователей

На этом этапе мы рассмотрим, как обеспечить безопасность нашего многоконтейнерного приложения и управление доступом. Это включает аутентификацию пользователей, шифрование данных, защиту API и настройку безопасных соединений между сервисами.

Цель: обеспечить, чтобы только зарегистрированные и аутентифицированные пользователи могли взаимодействовать с приложением и выполнять операции.

Реализация JWT (JSON Web Token) для аутентификации

Шаг 1. Установка необходимых библиотек:

Terminal

pip install Flask-JWT-Extended

Шаг 2. Настройка JWT в Flask-приложении:

Добавьте следующие изменения в файл backend/app/__init__.py:

Python

from flask_jwt_extended import JWTManager

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://taskuser:taskpassword@database:5432/taskdb'
app.config['JWT_SECRET_KEY'] = 'your_jwt_secret_key'  # Замените на ваш секретный ключ
db = SQLAlchemy(app)
jwt = JWTManager(app)
        
from app import routes    

Шаг 3. Создание маршрутов для регистрации и авторизации:

Добавьте следующие маршруты в файл backend/app/routes.py:

Python

from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from werkzeug.security import generate_password_hash, check_password_hash
from app.models import User, Task
        
@app.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    hashed_password = generate_password_hash(data['password'], method='sha256')
    new_user = User(username=data['username'], password=hashed_password)
    db.session.add(new_user)
    db.session.commit()
    return jsonify({'message': 'User registered successfully'}), 201
        
@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    user = User.query.filter_by(username=data['username']).first()
    if not user or not check_password_hash(user.password, data['password']):
        return jsonify({'message': 'Invalid credentials'}), 401

    access_token = create_access_token(identity=user.id)
    return jsonify({'access_token': access_token}), 200

@app.route('/tasks', methods=['GET'])
@jwt_required()
def get_tasks():
    current_user_id = get_jwt_identity()
    tasks = Task.query.filter_by(owner_id=current_user_id).all()
    return jsonify([task.to_dict() for task in tasks])

Шаг 4. Обновление модели User для хранения паролей:

Обновите файл backend/app/models.py:

Python

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    tasks = db.relationship('Task', backref='owner', lazy=True)

6.2 Шифрование данных

Цель: обеспечить защиту данных при передаче между клиентом и сервером.

Использование HTTPS

Шаг 1. Настройка Nginx в качестве реверс-прокси с поддержкой HTTPS:

Создайте файл nginx.conf в корневой директории проекта:

Text

server {
    listen 80;
    server_name your_domain.com;
        
    location / {
        proxy_pass http://frontend:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
        
    location /api {
        proxy_pass http://backend:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Шаг 2. Создание Dockerfile для Nginx:

Создайте файл Dockerfile в директории nginx:

dockerfile

FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf

Шаг 3. Добавление Nginx в compose.yaml:

Обновите файл compose.yaml, добавив сервис для Nginx:

Yaml

version: '3'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    networks:
      - task-network
        
  backend:
    build: ./backend
    ports:
      - "5000:5000"
    depends_on:
      - database
    networks:
      - task-network
    environment:
      - DATABASE_URL=postgresql://taskuser:taskpassword@database:5432/taskdb
        
  database:
    image: postgres:13
    environment:
      - POSTGRES_DB=taskdb
      - POSTGRES_USER=taskuser
      - POSTGRES_PASSWORD=taskpassword
    networks:
      - task-network
    volumes:
      - db-data:/var/lib/postgresql/data
        
  nginx:
    build: ./nginx
    ports:
      - "80:80"
    depends_on:
      - frontend
      - backend
    networks:
      - task-network
        
networks:
  task-network:
    driver: bridge
        
volumes:
  db-data:

6.3 Получение SSL сертификата с помощью Let's Encrypt

Шаг 1. Установка Certbot:

Следуйте инструкциям на официальном сайте Certbot для установки Certbot.

Шаг 2. Получение сертификата:

Terminal

sudo certbot certonly --standalone -d your_domain.com

Шаг 3. Настройка Nginx для использования SSL:

Обновите nginx.conf для использования SSL:

Text

server {
    listen 80;
    server_name your_domain.com;
    return 301 https://$host$request_uri;
}
        
server {
    listen 443 ssl;
    server_name your_domain.com;
        
    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
        
    location / {
        proxy_pass http://frontend:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
        
    location /api {
        proxy_pass http://backend:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Шаг 4. Обновление Dockerfile для Nginx для копирования сертификатов:

dockerfile

FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY /etc/letsencrypt /etc/letsencrypt

6.4 Защита API

Цель: ограничить доступ к API и предотвратить несанкционированные запросы.

Использование JWT для защиты маршрутов

Мы уже добавили защиту для маршрутов задач, используя декоратор @jwt_required(). Убедитесь, что все чувствительные маршруты защищены этим декоратором:

Python

from flask_jwt_extended import jwt_required, get_jwt_identity

@app.route('/tasks', methods=['GET'])
@jwt_required()
def get_tasks():
    current_user_id = get_jwt_identity()
    tasks = Task.query.filter_by(owner_id=current_user_id).all()
    return jsonify([task.to_dict() for task in tasks])

Ограничение доступа к базе данных

Цель: предотвратить несанкционированный доступ к базе данных.

Настройка ролей и привилегий

Шаг 1. Создание пользователя с ограниченными привилегиями:

SQL

CREATE USER limited_user WITH PASSWORD 'limited_password';
GRANT CONNECT ON DATABASE taskdb TO limited_user;
GRANT USAGE ON SCHEMA public TO limited_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO limited_user;

Шаг 2. Обновление переменной окружения DATABASE_URL:

Обновите переменную окружения DATABASE_URL в файле compose.yaml:

Yaml

environment:
  - DATABASE_URL=postgresql://limited_user:limited_password@database:5432/taskdb
3
Задача
Модуль 2: Fullstack, 18 уровень, 5 лекция
Недоступна
Настройка реверс-прокси Nginx
Настройка реверс-прокси Nginx
3
Задача
Модуль 2: Fullstack, 18 уровень, 5 лекция
Недоступна
Получение SSL сертификата с Let's Encrypt
Получение SSL сертификата с Let's Encrypt
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Илья Уровень 90
28 августа 2025
Следуйте инструкциям на официальном сайте Certbot для установки Certbot. Ссылка не рабочая, переправляет на эту же страницу