Autenticação - edu-almeidaf/reservas-academicas GitHub Wiki

Vídeo Explicativo: https://youtu.be/OKl6rILgd1E

Descrição Geral

A Entrega 4.1 implementa a autenticação do Reservas Acadêmicas e a separação entre a área administrativa e a área do usuário (RF01 — Fazer Login; RNF05 — controle de acesso por perfil). O usuário entra com o e-mail acadêmico e a senha e é levado para a área do seu perfil. Cada área só pode ser acessada pelo perfil a que pertence.

Perfil Área Rota Quem é
Discente Área do Discente /student Aluno (área do usuário)
Docente Área do Docente /teacher Professor (área do usuário)
Técnico Área Administrativa /admin Servidor com acesso administrativo

O que foi entregue

  • Login com e-mail e senha. A senha fica salva só como hash (password_hash/password_verify). E-mail inexistente e senha errada mostram a mesma mensagem, para não revelar quais e-mails estão cadastrados.
  • Logout por POST (botão "Sair" na barra superior). O ID da sessão é regenerado no login e no logout, para evitar session fixation.
  • Cadastro público de discentes e docentes em /signup. O perfil técnico não pode ser escolhido no cadastro, nem forjando a requisição: ele só é criado pelo populate.
  • Controle de acesso: o middleware auth protege as rotas autenticadas, e os middlewares student, teacher e admin exigem login e o perfil da área. Sem login, o usuário vai para o login com "Você deve estar logado para acessar essa página". Com outro perfil, volta para a própria área com "Você não tem permissão para acessar essa página".
  • A raiz / leva cada usuário à sua área, ou ao login se não houver sessão.
  • Testes automatizados: unitários (models e classes de apoio), de integração (controllers), de acesso às rotas públicas e autenticadas e de aceitação no navegador, cobrindo para os três perfis o acesso sem login, o login com dados incorretos, o login bem-sucedido, o logout, o bloqueio entre perfis e o cadastro.
  • CI no GitHub Actions em toda PR: testes, testes de aceitação, PHPCS e PHPStan.

Pull Request Principal

#14 — feat(auth): entrega 4.1 — autenticação com áreas por perfil (epic/autenticacao → main)

PRs internas da entrega (todas para a branch epic/autenticacao):

PR Título
#7 ci: configura GitHub Actions e alinha User ao schema
#8 feat(user): adiciona perfis e validações ao model User
#9 feat(auth): adiciona login e logout de usuários
#10 feat(auth): adiciona áreas por perfil com controle de acesso
#11 feat(user): adiciona cadastro de usuários
#12 test(auth): adiciona testes de aceitação do fluxo de autenticação
#13 docs: adiciona instruções de execução e dados de acesso ao README

Como Executar

Dependências: Docker e Docker Compose, com as portas 80, 8080 e 4444 livres.

Download

git clone https://github.com/edu-almeidaf/reservas-academicas.git
cd reservas-academicas

Execução

cp .env.example .env
./run composer install
./run codecept build
./run up -d

Banco de dados e populate

./run db:reset
./run db:populate

Logo após o up, o MySQL pode levar alguns segundos para aceitar conexões. Se o db:reset falhar, aguarde e rode de novo. Depois, acesse http://localhost.

Dados de acesso

Perfil E-mail Senha
Discente [email protected] 12345678
Docente [email protected] 12345678
Técnico (admin) [email protected] 12345678

Testes e qualidade

./run test           # unitários e de integração
./run test:browser   # aceitação (Codeception + Selenium)
./run phpcs
./run phpstan

Conceitos e Referências

Conceitos de autenticação aplicados nesta entrega, cada um com uma referência de livro: o trecho, a tradução, a página e como o conceito aparece no projeto. As traduções são livres. As páginas do Handbook of Applied Cryptography e do Security Engineering seguem a numeração impressa dos PDFs disponibilizados pelos autores.

Resumo

# Conceito Livro Página
1 Definição de autenticação Menezes et al., Handbook of Applied Cryptography p. 386
2 Autenticação × autorização Menezes et al., Handbook of Applied Cryptography (+ Anderson, p. 207) p. 387
3 Cookies e sessões Kurose e Ross, Redes de computadores e a internet (+ Manual do PHP) cap. 2
4 Sessão × outros métodos (JWT, tokens) Anderson, Security Engineering (+ RFC 7519) p. 140
5 Papel do middleware Fowler, Padrões de arquitetura de aplicações corporativas cap. 14
6 Outros tipos de autenticação Menezes et al., Handbook of Applied Cryptography p. 387
7 O que é 2FA e por que importa Anderson, Security Engineering p. 93

1. Definição de autenticação

Livro: MENEZES; VAN OORSCHOT; VANSTONE. Handbook of Applied Cryptography. Cap. 10, p. 386, Definição 10.1. PDF do capítulo: https://cacr.uwaterloo.ca/hac/about/chap10.pdf

"Entity authentication is the process whereby one party is assured (through acquisition of corroborative evidence) of the identity of a second party involved in a protocol [...]"

Tradução: "Autenticação de entidade é o processo pelo qual uma parte obtém a garantia (por meio de evidências que a comprovam) da identidade de uma segunda parte envolvida em um protocolo."

No projeto: o sistema (uma parte) obtém a garantia de quem é o usuário (a outra parte) pela evidência da senha, conferida em User::authenticate() com password_verify.

2. Autenticação × autorização

Livro: MENEZES et al. Handbook of Applied Cryptography. Cap. 10, p. 387, seção 10.1, "(iii) Applications of identification protocols".

"One of the primary purposes of identification is to facilitate access control to a resource, when an access privilege is linked to a particular identity [...]"

Tradução: "Um dos principais propósitos da identificação é viabilizar o controle de acesso a um recurso, quando um privilégio de acesso está ligado a uma identidade específica."

Complemento, com a definição de controle de acesso: ANDERSON. Security Engineering. 3. ed. Cap. 6, p. 207. PDF do capítulo: https://www.cl.cam.ac.uk/~rja14/Papers/SEv3-ch06.pdf

"Its function is to control which principals (persons, processes, machines, . . .) have access to which resources in the system [...]"

Tradução: "Sua função é controlar quais entidades (pessoas, processos, máquinas...) têm acesso a quais recursos do sistema."

No projeto:

  • Autenticação = "quem é você?": o login (AuthenticationsController::authenticate + Auth::login).
  • Autorização = "o que você pode acessar?": o privilégio ligado à identidade é o perfil (discente/docente/tecnico), e o controle de acesso são os middlewares student, teacher e admin (AuthorizeProfile). Um discente autenticado continua sem autorização para abrir /admin.

3. Cookies e sessões

Livro: KUROSE; ROSS. Redes de computadores e a internet. Cap. 2 (camada de aplicação), seção "Interação usuário-servidor: cookies".

Documentação oficial do PHP: Manual do PHP, "Sessões — uso básico": https://www.php.net/manual/pt_BR/session.examples.basic.php

"Sessões são uma forma simples de armazenar dados para usuários individuais usando um ID de sessão único. [...] IDs de sessão normalmente são enviados ao navegador através de cookies de sessão e o ID é usado para recuperar dados da sessão existente."

No projeto:

  1. O HTTP não guarda estado entre requisições.
  2. O session_start() (em config/bootstrap.php) cria a sessão e envia o cookie PHPSESSID com o ID.
  3. O navegador reenvia esse cookie em toda requisição.
  4. Os dados ($_SESSION['user']['id']) ficam no servidor; o navegador só guarda o ID.
  5. No login e no logout, session_regenerate_id(true) troca o ID, contra session fixation.

4. Sessão × outros métodos (tokens/JWT e HTTP Authentication)

Livro: ANDERSON. Security Engineering. 3. ed. Cap. 4, p. 140, ao tratar de OAuth e tokens de acesso. PDF do capítulo: https://www.cl.cam.ac.uk/~rja14/Papers/SEv3-ch04.pdf

"[...] the details are tied up with how cookies and web redirects operate and optimised to enable servers to be stateless, so they scale well for modern web services."

Tradução: "[...] os detalhes estão ligados ao funcionamento dos cookies e dos redirecionamentos web, e são otimizados para permitir que os servidores não guardem estado, escalando bem para serviços web modernos."

Definição de JWT (especificação oficial): RFC 7519, Abstract: https://www.rfc-editor.org/rfc/rfc7519

"JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties."

HTTP Basic Authentication (especificação oficial): RFC 7617, Abstract: https://www.rfc-editor.org/rfc/rfc7617

"This document defines the "Basic" Hypertext Transfer Protocol (HTTP) authentication scheme, which transmits credentials as user-id/password pairs, encoded using Base64."

Comparação:

Sessão + cookie (o projeto) JWT HTTP Basic
Onde ficam os dados No servidor ($_SESSION) Dentro do token (claims assinadas) Não há sessão: as credenciais vão em toda requisição
O que o navegador envia Só o ID (PHPSESSID) O token (geralmente no cabeçalho Authorization: Bearer ...) Authorization: Basic <usuário:senha em Base64>
Servidor guarda estado? Sim (stateful) Não (stateless) Não
Logout Fácil: apaga a sessão no servidor Difícil: o token vale até expirar Não existe de verdade (o navegador guarda as credenciais)
Bom para Aplicações web tradicionais (como esta) APIs e vários servidores Casos simples, sempre com HTTPS (Base64 não é criptografia)

5. Papel do middleware

Livro: FOWLER. Padrões de arquitetura de aplicações corporativas. Cap. 14, padrão Front Controller. Resumo do padrão no site do autor: https://martinfowler.com/eaaCatalog/frontController.html

"A controller that handles all requests for a Web site."

"In a complex Web site there are many similar things you need to do when handling a request."

Tradução: "Um controlador que trata todas as requisições de um site." / "Em um site complexo, há muitas coisas parecidas que você precisa fazer ao tratar uma requisição."

No projeto:

  • O front controller é o public/index.php com o Router: toda URL passa por ele.
  • As "coisas parecidas" feitas em toda requisição, como verificar o login e o perfil, ficam nos middlewares (Authenticate, AuthorizeStudent, AuthorizeTeacher, AuthorizeAdmin), que rodam antes do controller e podem barrar a requisição (flash + redirect + exit).
  • Route::middleware('auth')->group(...) pendura o middleware em todas as rotas do grupo, sem repetir a verificação em cada controller.

6. Outros tipos de autenticação além de e-mail e senha

Livro: MENEZES et al. Handbook of Applied Cryptography. Cap. 10, p. 387, seção 10.1, "(ii) Basis of identification".

"Entity authentication techniques may be divided into three main categories [...]: 1. something known [...] 2. something possessed [...] 3. something inherent (to a human individual)."

Tradução: "As técnicas de autenticação podem ser divididas em três categorias: 1. algo que se sabe (senha, PIN); 2. algo que se possui (cartão com chip, gerador de senhas); 3. algo inerente à pessoa (biometria: assinatura, digital, voz, retina)."

No projeto: usa só a primeira categoria (senha). Outros exemplos para citar:

  • Algo que possui: token físico, código no celular, certificado digital.
  • Algo inerente: digital, reconhecimento facial.
  • Delegada: login social (Google), LDAP/AD (a wiki cita LDAP/AD como desejável para o login acadêmico).

7. O que é 2FA e por que importa

Livro: ANDERSON. Security Engineering. 3. ed. Cap. 3, p. 93. PDF do capítulo: https://www.cl.cam.ac.uk/~rja14/Papers/SEv3-ch03.pdf

"[...] for important accounts – such as banking and email itself – standard practice is now to use a second factor. This is typically a code sent to your phone by SMS, or better still using an app [...]"

"Google research shows that SMSs stop all bulk password guessing by bots, 96% of bulk phishing and 76% of targeted attacks."

Tradução: "Para contas importantes, como banco e o próprio e-mail, a prática padrão hoje é usar um segundo fator, normalmente um código enviado ao celular por SMS ou, melhor ainda, por um aplicativo." / "Uma pesquisa do Google mostra que o SMS barra todas as tentativas automáticas de adivinhar senhas, 96% do phishing em massa e 76% dos ataques direcionados."

No projeto: 2FA é combinar dois fatores de categorias diferentes (conceito 6), por exemplo a senha (algo que se sabe) e um código no celular (algo que se possui). Se a senha vazar, ela sozinha não basta. O projeto ainda não tem 2FA; uma evolução possível é adotá-lo, por exemplo com um código enviado por e-mail após a senha.

Referências (ABNT)

ANDERSON, Ross. Security Engineering: a guide to building dependable distributed systems. 3. ed. Indianapolis: Wiley, 2020. Disponível em: https://www.cl.cam.ac.uk/~rja14/book.html.

FOWLER, Martin. Padrões de arquitetura de aplicações corporativas. Porto Alegre: Bookman, 2006.

KUROSE, James F.; ROSS, Keith W. Redes de computadores e a internet: uma abordagem top-down. 6. ed. São Paulo: Pearson, 2013.

MENEZES, Alfred J.; VAN OORSCHOT, Paul C.; VANSTONE, Scott A. Handbook of Applied Cryptography. Boca Raton: CRC Press, 1996. Disponível em: https://cacr.uwaterloo.ca/hac/.

Fontes complementares (especificações e documentação oficial):

Uso de Inteligência Artificial

Ferramentas utilizadas

  • Claude Code (Anthropic), usado no terminal e na extensão do VS Code, em todas as PRs da entrega.

Finalidade

Atividade PR Contribuição da IA
CI e base de testes #7 Criou o workflow do GitHub Actions a partir do projeto de referência e alinhou o model User ao schema do banco, corrigindo os 19 testes que falhavam
Perfis do usuário #8 Implementou as constantes e os métodos de perfil do User, as validações email e inclusion, o populate via model e os testes unitários
Login e logout #9 Implementou o AuthenticationsController, os layouts, o logout por POST, a regeneração do ID da sessão e os testes de integração e de acesso
Áreas por perfil #10 Criou os middlewares de autorização por perfil, as três áreas, o redirecionamento da raiz e os testes de acesso com login real
Cadastro #11 Implementou o cadastro com proteção contra mass assignment e contra a escolha do perfil técnico, e os testes
Testes de aceitação #12 Escreveu os testes de aceitação dos três perfis com exemplos do Codeception
Documentação #13 Redigiu o README e a primeira versão desta página, e validou as instruções num clone limpo

Exemplos de prompts e resultados

  1. Prompt: "Implemente os perfis discente, docente e técnico no model User, com as validações de perfil, e-mail e senha, e troque o seed em SQL por um seed via model" Resultado: constantes PROFILE_*, métodos isStudent(), isTeacher(), isAdmin(), hasProfile(), homeRouteName() e profileLabel(), as validações Validations::email() e Validations::inclusion(), o UsersPopulate e 9 testes unitários novos.
  2. Prompt: "Implemente o login e o logout, com logout por POST e regeneração do ID da sessão" Resultado: controller, layouts e Auth com session_regenerate_id(true). A ferramenta também validou o fluxo com curl: o ID da sessão muda após o login, e GET /logout responde 404.
  3. Prompt: "Crie uma área para cada perfil acessível só pelo próprio perfil, sem alterar o framework, e faça a raiz redirecionar para a área de quem está logado" Resultado: classe abstrata AuthorizeProfile (padrão Template Method) e um middleware por perfil. Como o framework executa o middleware do grupo interno antes do externo, os grupos de perfil ficaram fora do grupo auth, e cada middleware verifica o login sozinho.
  4. Prompt: "Implemente o cadastro de usuário (signup) com perfis discente/docente, protegido contra mass assignment" Resultado: UsersController, a view de cadastro, User::isValidForSignup() e os testes, incluindo um POST forjado com o perfil técnico e com user[id].
  5. Prompt: "Escreva os testes de aceitação do fluxo de autenticação para discente, docente e técnico" Resultado: Cests com #[Examples] por perfil para acesso sem login, login inválido e válido, logout, bloqueio entre perfis e cadastro.