181 lines
5.0 KiB
SQL
181 lines
5.0 KiB
SQL
Création de la base de données
|
|
```sql
|
|
CREATE DATABASE api_rest;
|
|
|
|
\c api_rest
|
|
|
|
CREATE TABLE users (
|
|
id SERIAL PRIMARY KEY,
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password VARCHAR(255) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE products (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
price DECIMAL(10, 2) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE orders (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
product_id INTEGER NOT NULL REFERENCES products(id),
|
|
quantity INTEGER NOT NULL,
|
|
total DECIMAL(10, 2) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX orders_user_id_idx (user_id),
|
|
INDEX orders_product_id_idx (product_id)
|
|
);
|
|
|
|
CREATE TABLE tokens (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
token TEXT NOT NULL,
|
|
expires_at TIMESTAMP NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX tokens_user_id_idx ON tokens (user_id);
|
|
|
|
CREATE TABLE logs (
|
|
id SERIAL PRIMARY KEY,
|
|
action VARCHAR(255) NOT NULL,
|
|
data JSONB,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE blacklisted_tokens (
|
|
id SERIAL PRIMARY KEY,
|
|
token TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE ip_limits (
|
|
id SERIAL PRIMARY KEY,
|
|
ip_address VARCHAR(255) NOT NULL,
|
|
limit INTEGER NOT NULL,
|
|
remaining INTEGER NOT NULL
|
|
);
|
|
```
|
|
|
|
Insertion de données de démo
|
|
```sql
|
|
INSERT INTO users (email, password) VALUES
|
|
('user1@example.com', '$2y$10$O4RzgF7rXUyL0B8HbBz4zOl2mS8sKQ3xMgFp2J9PfX8mPp1IwGz6s'),
|
|
('user2@example.com', '$2y$10$O4RzgF7rXUyL0B8HbBz4zOl2mS8sKQ3xMgFp2J9PfX8mPp1IwGz6s');
|
|
|
|
INSERT INTO products (name, description, price) VALUES
|
|
('Produit 1', 'Description du produit 1', 19.99),
|
|
('Produit 2', 'Description du produit 2', 9.99);
|
|
|
|
INSERT INTO orders (user_id, product_id, quantity, total) VALUES
|
|
(1, 1, 2, 39.98),
|
|
(1, 2, 1, 9.99);
|
|
|
|
INSERT INTO tokens (user_id, token, expires_at) VALUES
|
|
(1, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaGFuIjoiMjMwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', '2024-03-16 12:00:00');
|
|
|
|
INSERT INTO logs (action, data) VALUES
|
|
('CREATE', '{"user_id": 1, "product_id": 1}'::JSONB),
|
|
('UPDATE', '{"user_id": 1, "product_id": 2}'::JSONB);
|
|
|
|
INSERT INTO blacklisted_tokens (token) VALUES
|
|
('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaGFuIjoiMjMwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
|
|
|
|
INSERT INTO ip_limits (ip_address, limit, remaining) VALUES
|
|
('192.168.1.1', 100, 90);
|
|
```
|
|
|
|
Tableau des routes
|
|
```markdown
|
|
**POST /login** : Authentification JWT
|
|
* Requête : Application/x-www-form-urlencoded (email, password)
|
|
* Réponse : 200 OK (token refresh)
|
|
|
|
**POST /register** : Inscription
|
|
* Requête : Application/x-www-form-urlencoded (email, password)
|
|
* Réponse : 201 Created (token refresh)
|
|
|
|
**GET /products** : Récupération des produits
|
|
* Réponse : 200 OK (products)
|
|
|
|
**GET /products/:id** : Récupération d'un produit
|
|
* Paramètres : id (integer)
|
|
* Réponse : 200 OK (product)
|
|
|
|
**POST /products** : Création d'un produit
|
|
* Requête : Application/json (product)
|
|
* Réponse : 201 Created (product)
|
|
|
|
**PUT /products/:id** : Mise à jour d'un produit
|
|
* Paramètres : id (integer)
|
|
* Requête : Application/json (product)
|
|
* Réponse : 200 OK (product)
|
|
|
|
**DELETE /products/:id** : Suppression d'un produit
|
|
* Paramètres : id (integer)
|
|
* Réponse : 204 No Content
|
|
|
|
**GET /orders** : Récupération des commandes
|
|
* Répondre : 200 OK (orders)
|
|
|
|
**GET /orders/:id** : Récupération d'une commande
|
|
* Paramètres : id (integer)
|
|
* Répondre : 200 OK (order)
|
|
|
|
**POST /orders** : Création d'une commande
|
|
* Requête : Application/json (order)
|
|
* Répondre : 201 Created (order)
|
|
|
|
**PUT /orders/:id** : Mise à jour d'une commande
|
|
* Paramètres : id (integer)
|
|
* Requête : Application/json (order)
|
|
* Répondre : 200 OK (order)
|
|
|
|
**DELETE /orders/:id** : Suppression d'une commande
|
|
* Paramètres : id (integer)
|
|
* Répondre : 204 No Content
|
|
```
|
|
|
|
API REST Authentification JWT avec Node.js et Express.js
|
|
```javascript
|
|
const express = require('express');
|
|
const jwt = require('jsonwebtoken');
|
|
const mongoose = require('mongoose');
|
|
const dotenv = require('dotenv');
|
|
|
|
dotenv.config();
|
|
|
|
const app = express();
|
|
|
|
const usersSchema = new mongoose.Schema({
|
|
email: String,
|
|
password: String
|
|
});
|
|
|
|
const User = mongoose.model('User', usersSchema);
|
|
|
|
const productsSchema = new mongoose.Schema({
|
|
name: String,
|
|
description: String,
|
|
price: Number
|
|
});
|
|
|
|
const Product = mongoose.model('Product', productsSchema);
|
|
|
|
const ordersSchema = new mongoose.Schema({
|
|
userId: Number,
|
|
productId: Number,
|
|
quantity: Number,
|
|
total: Number
|
|
});
|
|
|
|
const Order = mongoose.model('Order', ordersSchema);
|
|
|
|
const logsSchema = new mongoose.Schema({
|
|
action |