O logout é o processo de invalidar tokens de acesso e garantir que a sessão seja encerrada de forma segura na API da Nuvende.
O logout na API da Nuvende é um processo simples que invalida o token de acesso atual. Quando você faz logout:
URL: POST /api/v2/auth/logout
Ambiente Homologação: https://api-h.nuvende.com.br/api/v2/auth/logout
Ambiente Produção: https://api.nuvende.com.br/api/v2/auth/logout
Authorization: Bearer {access_token} - Token de acesso a ser invalidadocurl -X POST https://api-h.nuvende.com.br/api/v2/auth/logout \
-H "Authorization: Bearer seu_access_token"
{
"message": "Successfully logged out"
}
Explicação da Resposta:
Vamos integrar o logout à classe NuvendeAuth que criamos na página de login:
const axios = require('axios');
class NuvendeAuth {
constructor(clientId, clientSecret, baseUrl) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseUrl = baseUrl;
this.accessToken = null;
this.tokenExpiry = null;
}
// ... outros métodos da classe (getAccessToken, etc.) ...
/**
* Realiza logout invalidando o token de acesso atual
* Após o logout, o token não pode mais ser usado
*/
async logout() {
// Verificar se temos um token para invalidar
if (!this.accessToken) {
console.log('Nenhum token ativo para fazer logout');
return { message: 'Nenhum token ativo' };
}
try {
console.log('Realizando logout...');
const response = await axios.post(`${this.baseUrl}/api/v2/auth/logout`, {}, {
headers: {
'Authorization': `Bearer ${this.accessToken}`
}
});
// Limpar tokens locais após logout bem-sucedido
this.clearTokens();
console.log('Logout realizado com sucesso');
return response.data;
} catch (error) {
console.error('Erro no logout:', error.response?.data || error.message);
// Mesmo com erro, limpar tokens locais por segurança
this.clearTokens();
throw error;
}
}
/**
* Limpa todos os tokens armazenados localmente
* Deve ser chamado após logout ou em caso de erro de autenticação
*/
clearTokens() {
this.accessToken = null;
this.tokenExpiry = null;
console.log('Tokens locais limpos');
}
/**
* Verifica se há um token ativo
*/
isAuthenticated() {
return this.accessToken !== null;
}
}
// Exemplo de uso prático
async function exemploLogout() {
const nuvende = new NuvendeAuth(
process.env.NUVENDE_CLIENT_ID,
process.env.NUVENDE_CLIENT_SECRET,
'https://api-h.nuvende.com.br'
);
try {
// Fazer login primeiro
await nuvende.getAccessToken();
console.log('Usuário autenticado');
// Fazer algumas operações...
console.log('Realizando operações...');
// Fazer logout
await nuvende.logout();
console.log('Logout realizado com sucesso');
// Verificar se ainda está autenticado
console.log('Ainda autenticado?', nuvende.isAuthenticated()); // false
} catch (error) {
console.error('Erro:', error.message);
}
}
import requests
import time
from datetime import datetime
class NuvendeAuth:
def __init__(self, client_id, client_secret, base_url):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = base_url
self.access_token = None
self.token_expiry = None
# ... outros métodos da classe (get_access_token, etc.) ...
def logout(self):
"""
Realiza logout invalidando o token de acesso atual
Após o logout, o token não pode mais ser usado
"""
if not self.access_token:
print("Nenhum token ativo para fazer logout")
return {"message": "Nenhum token ativo"}
try:
print("Realizando logout...")
headers = {
'Authorization': f'Bearer {self.access_token}'
}
response = requests.post(
f"{self.base_url}/api/v2/auth/logout",
headers=headers
)
response.raise_for_status()
# Limpar tokens locais após logout bem-sucedido
self.clear_tokens()
print("Logout realizado com sucesso")
return response.json()
except requests.exceptions.RequestException as e:
print(f"Erro no logout: {e}")
# Mesmo com erro, limpar tokens locais por segurança
self.clear_tokens()
raise
def clear_tokens(self):
"""
Limpa todos os tokens armazenados localmente
Deve ser chamado após logout ou em caso de erro de autenticação
"""
self.access_token = None
self.token_expiry = None
print("Tokens locais limpos")
def is_authenticated(self):
"""
Verifica se há um token ativo
"""
return self.access_token is not None
# Exemplo de uso prático
async def exemplo_logout():
nuvende = NuvendeAuth(
os.getenv('NUVENDE_CLIENT_ID'),
os.getenv('NUVENDE_CLIENT_SECRET'),
'https://api-h.nuvende.com.br'
)
try:
# Fazer login primeiro
await nuvende.get_access_token()
print("Usuário autenticado")
# Fazer algumas operações...
print("Realizando operações...")
# Fazer logout
await nuvende.logout()
print("Logout realizado com sucesso")
# Verificar se ainda está autenticado
print(f"Ainda autenticado? {nuvende.is_authenticated()}") # False
except Exception as error:
print(f"Erro: {error}")
Após fazer logout, é importante limpar todos os vestígios de tokens no cliente:
// Limpar tokens do localStorage/sessionStorage
function clearStoredTokens() {
localStorage.removeItem('nuvende_access_token');
localStorage.removeItem('nuvende_refresh_token');
localStorage.removeItem('nuvende_token_expiry');
sessionStorage.removeItem('nuvende_access_token');
sessionStorage.removeItem('nuvende_refresh_token');
sessionStorage.removeItem('nuvende_token_expiry');
}
// Limpar cookies de autenticação
function clearAuthCookies() {
document.cookie = 'nuvende_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
document.cookie = 'nuvende_refresh_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
}
// Limpar dados da memória
function clearMemoryTokens() {
// Se estiver usando variáveis globais
window.nuvendeToken = null;
window.nuvendeRefreshToken = null;
}
Para aplicações web, implemente middleware que verifica tokens invalidados:
// Express.js middleware para verificar tokens
function authMiddleware(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'Token não fornecido' });
}
// Aqui você pode verificar se o token foi invalidado
// (implementar cache ou banco de tokens invalidados)
if (isTokenInvalidated(token)) {
return res.status(401).json({
error: 'Token invalidado. Faça login novamente.'
});
}
next();
}
// Função para verificar se token foi invalidado
function isTokenInvalidated(token) {
// Implementar lógica para verificar se token está na lista de invalidados
// Pode usar Redis, banco de dados ou cache em memória
return false; // Implementar conforme sua arquitetura
}
| Código | Significado | Quando Ocorre | Como Resolver |
|---|---|---|---|
200 | OK | Logout realizado com sucesso | - |
401 | Unauthorized | Token inválido ou expirado | Fazer login novamente |
500 | Internal Server Error | Erro interno do servidor | Tentar novamente mais tarde |
class LogoutErrorHandler {
static handleLogoutError(error) {
const status = error.response?.status;
const data = error.response?.data;
switch (status) {
case 401:
console.error('❌ Token inválido ou expirado:', data);
// Redirecionar para login ou solicitar nova autenticação
this.redirectToLogin();
break;
case 500:
console.error('❌ Erro interno do servidor:', data);
// Tentar novamente após um tempo
setTimeout(() => this.retryLogout(), 5000);
break;
default:
console.error('❌ Erro inesperado no logout:', error.message);
// Limpar tokens locais mesmo com erro
this.clearLocalTokens();
}
}
static redirectToLogin() {
// Implementar redirecionamento para página de login
window.location.href = '/login';
}
static retryLogout() {
// Implementar retry do logout
console.log('Tentando logout novamente...');
}
static clearLocalTokens() {
// Limpar tokens locais em caso de erro
localStorage.removeItem('nuvende_access_token');
localStorage.removeItem('nuvende_refresh_token');
}
}
// Quando usuário clica em "Sair"
async function handleUserLogout() {
try {
await nuvende.logout();
clearStoredTokens();
clearAuthCookies();
redirectToLogin();
} catch (error) {
LogoutErrorHandler.handleLogoutError(error);
}
}
// Logout automático após período de inatividade
let inactivityTimer;
function resetInactivityTimer() {
clearTimeout(inactivityTimer);
inactivityTimer = setTimeout(async () => {
console.log('Inatividade detectada, fazendo logout...');
await nuvende.logout();
clearStoredTokens();
redirectToLogin();
}, 30 * 60 * 1000); // 30 minutos
}
// Resetar timer em eventos de atividade
document.addEventListener('mousemove', resetInactivityTimer);
document.addEventListener('keypress', resetInactivityTimer);
// Logout imediato em caso de suspeita de segurança
async function securityLogout() {
try {
// Fazer logout no servidor
await nuvende.logout();
} catch (error) {
// Mesmo com erro, limpar dados locais
console.error('Erro no logout de segurança:', error);
} finally {
// Sempre limpar dados locais
clearStoredTokens();
clearAuthCookies();
clearMemoryTokens();
redirectToLogin();
}
}