Досягнення перевірки JWT токенів у Flask та React з PostgreSQL

текст перекладу

У цій статті я розповім, як я реалізував надійну систему автентифікації з перевіркою JWT токенів у бекенді Flask, фронтенді React і використанням PostgreSQL як бази даних. Це налаштування забезпечує безпечну автентифікацію користувачів і контроль доступу на основі ролей. Давайте зануримося!

pic

Фото 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. Тестування робочого процесу

Вхід

  1. Запустіть Flask бекенд: python run.py
  2. Запустіть React фронтенд: npm run dev
  3. Введіть дані для входу на фронтенді та перевірте, чи токен зберігається в localStorage.

Доступ для адміністраторів

  1. Використайте збережений токен для запиту до /admin/users.
  2. Переконайтесь, що лише користувачі з роллю адміністратора можуть отримати доступ до цього маршруту.

Висновок

Комбінуючи Flask, React та PostgreSQL, я реалізував безпечну систему автентифікації за допомогою JWT токенів. Це налаштування є масштабованим, безпечним і складає надійну основу для будь-якого застосунку на основі ролей.

Не соромтесь адаптувати цей процес для ваших проектів! Якщо у вас є питання, залиште їх у коментарях.

Перекладено з: Achieving JWT Token Verification in Flask and React with PostgreSQL

Leave a Reply

Your email address will not be published. Required fields are marked *