Autenticação 2

Após um processo de pentest na empresa, decidimos revisar e melhorar a segurança do processo de autenticação da nossa aplicação. O fluxo, após revisão, será o seguinte:

  1. Usuário envia uma requisição POST /auth.
  2. Credenciais de acesso são validadas.
    1. Se credenciais forem inválidas: Usuário recebe uma resposta 403.
    2. Se credenciais forem válidas: Usuário recebe um JWT de autenticação e outro de refresh.

Usaremos tokens JWT (https://jwt.io/) para autenticação por ser um formato conhecidamente seguro, logo quaisquer falhas de segurança já foram anteriormente idenficadas e corrigidas. Assim nosso processo de autenticação será feito com segurança.

Exemplo de resposta da requisição:

{
    "auth": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM
0NTY3ODkwIiwidHlwZSI6ImF1dGgiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1
MTYyMzkwMjJ9.hyTUti4JMhAhbEmiAgLf79Lih2OO7JMceJmDLUK8Qh0",
    "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIx
MjM0NTY3ODkwIiwidHlwZSI6InJlZnJlc2giLCJuYW1lIjoiSm9obiBEb2UiLCJpY
XQiOjE1MTYyMzk5MjJ9.jmQrkCt1KTg2gNH4oZzM3TASzq2hU3HZOBlK_r20CVk"
}

O token auth será usado como o token de autenticação, e o token refresh será usado para obter um novo token de autenticação. O token auth deve ter um tempo de expiração máximo de 5 minutos. O token refresh deve ter um tempo de expiração no mínimo 15 minutos mais longo do que o token auth.

O seguinte fluxo será usado para fazer a atualização do token auth:

  1. Usuário envia uma requisição POST /refresh com o token refresh.
  2. O token refresh é validado para verificar se é um JWT válido e não expirado.
    1. Se for válido e não tiver expirado: Usuário recebe um retorno idêntico à POST /auth com os novos tokens de auth e refresh.
    2. Se for inválido ou expirado: Usuário recebe uma resposta 403.

Para garantir ainda mais segurança para o usuário, é importante permitir que ele altere sua senha. Por isso, vamos adicionar um novo endpoint para a alteração da senha do usuário:

POST /change-password

Exemplo de request:

{
    "current_password": "passwd123",
    "new_password": "passwd123456"
}

O endpoint deve validar se a hash da senha current_password bate com a senha atual do usuário. Se sim, então a senha do usuário será atualizada. Se não, então retorna 403.

POST /forgot-password

Também é importante garantir que o usuário não perca acesso à sua conta. Para isso, esse endpoint poderá ser usado para disparar um e-mail para o usuário onde ele poderá fazer o processo de alteração de senha.

Exemplo de request:

{
    "email": "email@example.com"
}
  1. Se o email existir: Gera um novo token de recuperação de senha (um valor aleatório de 32 caracteres) e envia um e-mail para o usuário com o link para a tela de recuperação de senha, com o token no query parameter token. Esse token terá um tempo de expiração de 30 minutos.
  2. Se não existir: Retorna a mesma mensagem como se o e-mail existisse, mas não faz nada.

IMPORTANTE: Usaremos uma implementação segura para a geração do token aleatório, para garantir que ele não possa ser adivinhado.

POST /reset-password

Esse endpoint será o utilizado para definir uma nova senha para o usuário.

Exemplo de request:

{
    "email": "email@example.com",
    "token": "<32-chars-token>",
    "password": "newpasswd123"
}