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:
- Solicitação de credenciais: O utilizador insere o nome de utilizador e a palavra-passe num formulário no site ou na aplicação.
- 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. - 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).
- 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.
- 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
- 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>).
- Se for usado um ID de sessão, este é geralmente transmitido na cabeçalho HTTP
- 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
HttpOnlypara proteção contra XSS). É recomendável usar cookiesHttpOnlypara 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 cookiesHttpOnly.
- 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>).
- 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).
- 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).
- 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 Unauthorizedou403 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.