текст перекладу
У цій статті я розповім, як я реалізував надійну систему автентифікації з перевіркою JWT токенів у бекенді Flask, фронтенді React і використанням PostgreSQL як бази даних. Це налаштування забезпечує безпечну автентифікацію користувачів і контроль доступу на основі ролей. Давайте зануримося!
Фото Ed Hardie на Unsplash
1. Налаштування бекенду з Flask
Структура директорій
Ось структура директорій, яку я використовував:
project_root/
├── app/
│ ├── __init__.py
│ ├── auth.py # Маршрути для автентифікації
│ ├── models.py # Моделі бази даних
│ └── utils.py # Допоміжні функції, такі як генерація JWT
├── migrations/ # Міграції бази даних
├── .env
├── requirements.txt
├── run.py # Точка входу
Налаштування Flask та PostgreSQL
Спочатку потрібно встановити необхідні бібліотеки:
# додайте це у requirements.txt
Flask
psycopg2-binary
psycopg2
Flask-Migrate
Flask-JWT-Extended
python-dotenv
pip install -r requirements.txt
Я стикнувся з помилкою при встановленні psycopg2, тому я встановив залежність, яку він вимагає:
sudo apt update
sudo apt install libpq-dev
Я ініціалізував Flask додаток і налаштував його для підключення до моєї бази даних PostgreSQL:
# app/__init__.py
from flask import Flask
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from flask_bcrypt import Bcrypt
import psycopg2app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'your_jwt_secret_key'
CORS(app)
JWTManager(app)
Bcrypt = Bcrypt(app)
# Налаштування підключення до бази даних
def get_db_connection():
return psycopg2.connect(
host="localhost",
database="hospital_db",
user="your_username",
password="your_password"
)
2. Створення API для автентифікації
Маршрут для входу
Я створив маршрут для входу, щоб автентифікувати користувачів та видавати JWT токени:
# app/auth.py
from flask import Blueprint, request, jsonify
from flask_jwt_extended import create_access_token
from werkzeug.security import check_password_hash
from . import get_db_connection
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login', methods=['POST'])
def login():
data = request.get_json()
email = data.get('email')
password = data.get('password')
query = """
SELECT id, password_hash, role FROM users WHERE email = %s;
"""
with get_db_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(query, (email,))
user = cursor.fetchone()
if not user or not check_password_hash(user[1], password):
return jsonify({"error": "Invalid credentials"}), 401
token = create_access_token(identity={"id": user[0], "role": user[2]})
return jsonify({"token": token, "role": user[2]}), 200
3. Контроль доступу на основі ролей
Для захисту маршрутів лише для адміністраторів я перевіряв роль користувача, що зберігається у JWT токені:
@auth_bp.route('/admin/users', methods=['GET'])
@jwt_required()
def get_users():
current_user = get_jwt_identity()
if current_user['role'] != 'admin':
return jsonify({"error": "Unauthorized"}), 403
query = "SELECT id, username, email, role FROM users;"
with get_db_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(query)
users = cursor.fetchall()
return jsonify({
"users": [
{"id": user[0], "username": user[1], "email": user[2], "role": user[3]} for user in users
]
}), 200
текст перекладу
## Підключення React фронтенду
### Встановлення Vite та Tailwind CSS
Я використовував Vite як менеджер пакетів для React за його швидкість і простоту:
npm create vite@latest my-app --template react
cd my-app
npm install
Нижченаведений крок необхідний лише, якщо ви хочете використовувати Tailwind CSS, якщо ні — можна пропустити
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Скопіюйте це в зазначений файл шляху
Конфігурація tailwind.config.js для увімкнення Tailwind у проекті:
module.exports = {
content: ['./src/*/.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
```
/* оновіть index.css наступним кодом
необхідно лише, якщо встановлений Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;
Виконання API запитів
Ось як я обробляв вхід користувача у React, використовуючи Axios:
import axios from 'axios';
const login = async (email, password) => {
try {
const response = await axios.post('http://localhost:5000/login', {
email,
password,
});
localStorage.setItem('token', response.data.token);
console.log('Вхід успішний:', response.data);
} catch (error) {
console.error('Не вдалося увійти:', error.response.data);
}
};
5. Виправлення проблем з CORS
Для дозволу запитів з React фронтенду я налаштував Flask-CORS:
# app/__init__.py
from flask_cors import CORS
CORS(app, resources={r"/*": {"origins": "http://localhost:5173"}})
6. Тестування робочого процесу
Вхід
- Запустіть Flask бекенд:
python run.py
- Запустіть React фронтенд:
npm run dev
- Введіть дані для входу на фронтенді та перевірте, чи токен зберігається в localStorage.
Доступ для адміністраторів
- Використайте збережений токен для запиту до
/admin/users
. - Переконайтесь, що лише користувачі з роллю адміністратора можуть отримати доступ до цього маршруту.
Висновок
Комбінуючи Flask, React та PostgreSQL, я реалізував безпечну систему автентифікації за допомогою JWT токенів. Це налаштування є масштабованим, безпечним і складає надійну основу для будь-якого застосунку на основі ролей.
Не соромтесь адаптувати цей процес для ваших проектів! Якщо у вас є питання, залиште їх у коментарях.
Перекладено з: Achieving JWT Token Verification in Flask and React with PostgreSQL