Sobes.tech
Junior

Como funciona o processo de autenticação?

sobes.tech IA

Resposta da IA

O processo de autenticação do utilizador numa aplicação frontend geralmente consiste nos seguintes passos:

  1. Solicitação de credenciais: O utilizador insere o nome de utilizador e a palavra-passe num formulário no site ou na aplicação.
  2. Envio de dados ao servidor: O frontend envia esses dados ao servidor (backend) através de uma requisição HTTP (geralmente POST) a um endpoint de autenticação específico. Os dados podem ser enviados no corpo da requisição em formato JSON ou FormData.
  3. Verificação no servidor: O backend recebe os dados, verifica se existem na sua base de dados (por exemplo, se o nome de utilizador corresponde a um utilizador existente e se o hash da palavra-passe inserida corresponde ao hash armazenado).
  4. Geração de token/sessão: Se as credenciais estiverem corretas, o servidor gera um token de autenticação único. Isto pode ser:
    • ID de sessão: O servidor cria uma sessão e liga-a ao utilizador, enviando ao cliente um identificador de sessão (por exemplo, numa cookie com a flag HttpOnly).
    • Token (por exemplo, JWT): O servidor gera um token contendo informações sobre o utilizador e os seus direitos, assinando-o com a sua chave secreta. Este token é enviado ao cliente.
  5. Envio do token/sessão ao cliente: O servidor responde ao frontend enviando o token de autenticação gerado.
    • Se for usado um ID de sessão, este é geralmente transmitido na cabeçalho HTTP Set-Cookie.
    • Se for usado um token, pode ser enviado no corpo da resposta (JSON) ou na cabeçalho Authorization (por exemplo, Bearer <token>).
  6. Armazenamento do token no cliente: O frontend recebe o token e guarda-o para futuras requisições.
    • O ID de sessão é guardado automaticamente nos cookies do navegador.
    • O token pode ser guardado em localStorage, sessionStorage ou cookies (com a flag HttpOnly para proteção contra XSS). É recomendável usar cookies HttpOnly para tokens de acesso, pois isso reduz o risco de roubo por ataques XSS. Para JWT, também pode ser guardado um token de atualização em cookies HttpOnly.
  7. Utilização do token para requisições protegidas: Em requisições subsequentes a recursos protegidos (que requerem autenticação), o frontend envia o token guardado em cada requisição.
    • Para sessões, o navegador envia automaticamente os cookies correspondentes com o ID de sessão.
    • Para tokens, o frontend deve adicionar explicitamente o token no cabeçalho Authorization (por exemplo, Authorization: Bearer <token>).
  8. Verificação do token no servidor: Ao receber cada requisição a um recurso protegido, o servidor extrai o token da requisição e verifica a sua validade (por exemplo, a expiração do token, a assinatura do token, a existência de uma sessão com esse ID).
  9. Autorização: Se o token for válido, o servidor determina qual o utilizador associado a esse token e verifica os seus direitos de acesso ao recurso solicitado (isto é, o processo de autorização, após a autenticação).
  10. Execução da requisição: Se o utilizador estiver autenticado e autorizado, o servidor executa a requisição e envia a resposta. Caso contrário, envia um erro (por exemplo, 401 Unauthorized ou 403 Forbidden).

Os esquemas de autenticação variam (baseados em sessões, tokens JWT, OAuth2, OpenID Connect, etc.), mas os passos básicos para obter e usar um token para identificar o utilizador permanecem semelhantes.

Exemplo de envio de dados ao servidor (usando fetch API e token):

// Dados do utilizador
const userData = {
  username: 'user123',
  password: 'securepassword'
};

// Envio de dados ao servidor
fetch('/api/login', { // Endpoint de autenticação no servidor
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(userData)
})
.then(response => {
  if (!response.ok) {
    throw new Error('Falha no login');
  }
  return response.json(); // Espera-se que o servidor retorne JSON com o token
})
.then(data => {
  const authToken = data.token; // Obter o token da resposta do servidor
  localStorage.setItem('authToken', authToken); // Guardar o token (por exemplo, em localStorage)
  console.log('Login bem-sucedido, token guardado.');
  // Redirecionar o utilizador para uma página protegida
})
.catch(error => {
  console.error('Erro de autenticação:', error);
  // Mostrar mensagem de erro ao utilizador
});

// Exemplo de requisição protegida usando o token guardado
const token = localStorage.getItem('authToken');
if (token) {
  fetch('/api/protected-resource', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}` // Adicionar o token no cabeçalho Authorization
    }
  })
  .then(response => {
    if (!response.ok) {
      if (response.status === 401) {
        console.log('Token expirado ou inválido. Redirecionando para login.');
        // O token não é válido, limpar e redirecionar para login
        localStorage.removeItem('authToken');
        // window.location.href = '/login'; // Exemplo de redirecionamento
      }
      throw new Error('Falha ao obter recurso protegido');
    }
    return response.json();
  })
  .then(data => {
    console.log('Dados protegidos:', data);
  })
  .catch(error => {
    console.error('Erro ao obter recurso protegido:', error);
  });
} else {
  console.log('Nenhum token de autenticação encontrado. Redirecionando para login.');
  // window.location.href = '/login'; // Exemplo de redirecionamento
}

Aspectos importantes de segurança:

  • Sempre use HTTPS para enviar credenciais e tokens, evitando interceptações.
  • Armazene os tokens de forma segura (evite guardar informações sensíveis como senhas ou tokens de acesso no código ou em campos públicos).
  • Para tokens JWT: use uma duração curta para os tokens de acesso e atualize-os com tokens de atualização armazenados em cookies HttpOnly. Os tokens de acesso podem ser armazenados na memória da aplicação ou em localStorage, considerando os riscos de XSS.
  • Valide todos os dados no servidor.