API RESTful completa desenvolvida em PHP puro para gerenciamento de clientes, com autenticação JWT, reset de senha e operações CRUD seguras.
Esta API foi desenvolvida como projeto de estudos para demonstrar conhecimentos em:
- Desenvolvimento de APIs REST
- Autenticação e autorização com JWT
- Operações CRUD (Create, Read, Update, Delete)
- Segurança em aplicações web
- Boas práticas de programação em PHP
- Login com geração de token JWT
- Autenticação Bearer Token em rotas protegidas
- Expiração automática de tokens (1 hora)
- ✅ Criar novo cliente (cadastro)
- ✅ Listar todos os clientes
- ✅ Buscar cliente específico por ID
- ✅ Atualizar dados do próprio perfil
- ✅ Deletar própria conta (com cascata em pedidos)
- Solicitar reset de senha via email
- Resetar senha com token de segurança
- Token com validade de 15 minutos
Veja um exemplo de consumo desta API: Cliente API PHP
- PHP 8.2+ - Linguagem principal
- PDO - Conexão segura com banco de dados
- MySQL - Banco de dados relacional
- JWT (Firebase PHP-JWT) - Autenticação via tokens
- Carbon - Manipulação de datas
- Composer - Gerenciador de dependências
- phpdotenv - Gerenciamento de variáveis de ambiente
git clone https://github.com/EdsonAkaves/php-vanilla-crud-api.git
cd php-vanilla-crud-apicomposer installCrie um banco de dados MySQL e execute o script SQL:
CREATE DATABASE api_clientes;
USE api_clientes;
CREATE TABLE clientes (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
senha VARCHAR(255) NOT NULL,
reset_token VARCHAR(255) NULL,
reset_token_expira_em DATETIME NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE pedidos (
id INT AUTO_INCREMENT PRIMARY KEY,
id_cliente INT NOT NULL,
descricao TEXT,
valor DECIMAL(10,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (id_cliente) REFERENCES clientes(id) ON DELETE CASCADE
);Crie um arquivo .env na raiz do projeto:
# Banco de Dados
DB_HOST=localhost
DB_NAME=api_clientes
DB_USER=root
DB_PASS=
# JWT
JWT_SECRET_KEY=sua_chave_secreta_super_segura_aqui# Usando o servidor embutido do PHP
php -S localhost:8000
# Ou configure no Apache/Nginx
# Coloque o projeto na pasta htdocs/wwwhttp://localhost:8000/api
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /criar_cliente.php |
Cadastrar novo cliente |
| POST | /login.php |
Fazer login e obter token |
| GET | /clientes.php |
Listar todos os clientes |
| GET | /cliente.php?id={id} |
Buscar cliente por ID |
| POST | /solicitar_reset_senha.php |
Solicitar reset de senha |
| POST | /resetar_senha.php |
Resetar senha com token |
| Método | Endpoint | Descrição |
|---|---|---|
| PUT | /atualizar_cliente.php?id={id} |
Atualizar próprio perfil |
| DELETE | /deletar_cliente.php?id={id} |
Deletar própria conta |
POST /api/criar_cliente.php
Content-Type: application/json
{
"nome": "João Silva",
"email": "joao@exemplo.com",
"senha": "senha123"
}Resposta (201):
{
"Sucesso": "Cliente criado."
}POST /api/login.php
Content-Type: application/json
{
"email": "joao@exemplo.com",
"senha": "senha123"
}Resposta (200):
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}GET /api/clientes.phpResposta (200):
[
{
"id": 1,
"nome": "João Silva",
"email": "joao@exemplo.com"
},
{
"id": 2,
"nome": "Maria Santos",
"email": "maria@exemplo.com"
}
]PUT /api/atualizar_cliente.php?id=1
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...
{
"nome": "João Silva Junior",
"email": "joao.junior@exemplo.com"
}Resposta (200):
{
"Sucesso": "Cliente alterado com sucesso."
}POST /api/solicitar_reset_senha.php
Content-Type: application/json
{
"email": "joao@exemplo.com"
}Resposta (200):
{
"mensagem": "Se o e-mail existir, um link de reset foi enviado.",
"token_para_teste": "a1b2c3d4e5..."
}POST /api/resetar_senha.php
Content-Type: application/json
{
"token": "a1b2c3d4e5...",
"senha": "nova_senha_123"
}Resposta (200):
{
"sucesso": "Senha redefinida com sucesso."
}DELETE /api/deletar_cliente.php?id=1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...Resposta (200):
{
"Sucesso": "Cliente deletado."
}- ✅ Senhas hasheadas com
password_hash()(bcrypt) - ✅ JWT para autenticação stateless
- ✅ Prepared Statements (PDO) contra SQL Injection
- ✅ Validação de dados em todas as requisições
- ✅ Autorização por usuário - usuários só podem modificar seus próprios dados
- ✅ Tokens de reset com expiração de 15 minutos
- ✅ Headers de segurança (Content-Type, métodos HTTP)
- ✅ Variáveis de ambiente para dados sensíveis
php-vanilla-crud-api/
├── api/
│ ├── atualizar_cliente.php
│ ├── auth.php
│ ├── cliente.php
│ ├── clientes.php
│ ├── criar_cliente.php
│ ├── deletar_cliente.php
│ ├── login.php
│ ├── resetar_senha.php
│ └── solicitar_reset_senha.php
├── config/
│ └── database.php
├── vendor/
├── .env
├── .gitignore
├── bootstrap.php
├── composer.json
└── README.md
| Código | Significado |
|---|---|
| 200 | Sucesso |
| 201 | Criado com sucesso |
| 400 | Requisição inválida |
| 401 | Não autenticado |
| 403 | Sem permissão |
| 404 | Não encontrado |
| 405 | Método não permitido |
| 500 | Erro no servidor |
# Login
curl -X POST http://localhost:8000/api/login.php \
-H "Content-Type: application/json" \
-d '{"email":"joao@exemplo.com","senha":"senha123"}'
# Atualizar (com token)
curl -X PUT http://localhost:8000/api/atualizar_cliente.php?id=1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-d '{"nome":"João Atualizado"}'- Importe a collection (ou crie manualmente)
- Configure a variável
{{baseUrl}}comohttp://localhost:8000/api - Após o login, salve o token em uma variável
- Use o token nos endpoints protegidos
- Implementar paginação na listagem de clientes
- Adicionar filtros e ordenação
- Sistema de logs de auditoria
- Rate limiting para prevenir ataques
- Envio real de emails para reset de senha
- Documentação com Swagger/OpenAPI
- Testes automatizados (PHPUnit)
- Cache de requisições
- Versionamento da API (v1, v2)
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Edson Alves
- LinkedIn: edsonakaves
- GitHub: @EdsonAkaves
- Email: edson.akaves@gmail.com
Desenvolvido como projeto de estudos
⭐ Se este projeto te ajudou, considere dar uma estrela!