Pular para o conteúdo principal
ℹ️ Conteúdo em atualização

Estamos revisando estes procedimentos. Pessoas técnicas podem encontrar ajustes em códigos de erro ou mapeamentos de payload; valide com os logs e o OpenAPI mais recente. Pessoas não técnicas podem continuar usando o passo a passo e acionar o time de suporte caso algo pareça diferente do descrito.

🔐 Fluxo de Login

Este guia apresenta o fluxo completo de autenticação para usuários já cadastrados no sistema.

📋 Visão Geral

O fluxo de login permite que usuários autentiquem-se usando CPF e senha, gerando tokens de acesso OAuth 2.0 válidos por 5 minutos.

🔑 1. Login com Usuário e Senha

Para autenticar um usuário no sistema, você precisa gerar um token de acesso OAuth 2.0.

Endpoint

POST https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

Exemplos de Código

cURL

curl -X POST 'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET' \
-d 'username=12345678909' \
-d 'password=SenhaDoUsuario' \
-d 'grant_type=password' \
-d 'infosAdicionais={"dispositivoId":"device123","modelo":"Samsung Galaxy"}'

JavaScript

const response = await fetch('https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
username: '12345678909',
password: 'SenhaDoUsuario',
grant_type: 'password',
infosAdicionais: JSON.stringify({
dispositivoId: 'device123',
modelo: 'Samsung Galaxy'
})
})
});

const data = await response.json();
console.log(data.access_token);

Python

import requests

url = 'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token'
data = {
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET',
'username': '12345678909',
'password': 'SenhaDoUsuario',
'grant_type': 'password',
'infosAdicionais': '{"dispositivoId":"device123","modelo":"Samsung Galaxy"}'
}

response = requests.post(url, data=data)
tokens = response.json()
print(tokens['access_token'])

Java

HttpClient client = HttpClient.newHttpClient();
Map<String, String> data = new HashMap<>();
data.put("client_id", "YOUR_CLIENT_ID");
data.put("client_secret", "YOUR_CLIENT_SECRET");
data.put("username", "12345678909");
data.put("password", "SenhaDoUsuario");
data.put("grant_type", "password");
data.put("infosAdicionais", "{\"dispositivoId\":\"device123\"}");

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(
data.entrySet().stream()
.map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"))
))
.build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

📥 Parâmetros da Requisição

ParâmetroTipoObrigatórioDescrição
client_idstringID do cliente fornecido pela equipe
client_secretstringSecret do cliente (mantenha seguro!)
usernamestringCPF do usuário (apenas números)
passwordstringSenha do usuário
grant_typestringFixo: password
infosAdicionaisJSON stringInformações do dispositivo codificadas

📤 Resposta de Sucesso

200 OK
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI...",
"expires_in": 300,
"refresh_expires_in": 1800,
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "f3d2e1c0-b9a8-7654-3210-abcdef123456",
"scope": "profile email"
}
💡 Importante
  • Guarde o access_token e o refresh_token de forma segura
  • O access_token expira em 5 minutos (expires_in: 300)
  • Use o refresh_token para renovar sem pedir credenciais novamente
  • NUNCA exponha o client_secret em código frontend
⚠️ Segurança

O grant type password é adequado apenas para aplicações mobile/desktop de primeira parte. Para aplicações web, use Authorization Code Flow com PKCE.


🔄 2. Renovação de Token (Refresh Token)

Quando o token de acesso expirar (após 5 minutos), você pode renová-lo usando o refresh token sem precisar das credenciais do usuário.

Endpoint

POST https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

Exemplos de Código

cURL

curl -X POST 'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET' \
-d 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldU...' \
-d 'grant_type=refresh_token'

JavaScript

async function refreshAccessToken(refreshToken) {
const response = await fetch(
'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token',
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
refresh_token: refreshToken,
grant_type: 'refresh_token'
})
}
);

if (!response.ok) {
throw new Error('Token refresh failed');
}

return await response.json();
}

📥 Parâmetros da Requisição

ParâmetroTipoDescrição
client_idstringID do cliente
client_secretstringSecret do cliente
refresh_tokenstringRefresh token obtido no login
grant_typestringFixo: refresh_token
🔄 Estratégia de Renovação

Renove o token antes de expirar:

  • Configure um timer para renovar 1 minuto antes da expiração
  • Ou renove automaticamente ao receber erro 401 em suas requisições

🤖 3. Autenticação com Service Account

Para operações que não envolvem um usuário específico (server-to-server), use a autenticação de service account.

Endpoint

POST https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

Exemplos de Código

cURL

curl -X POST 'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=YOUR_SERVICE_ACCOUNT_ID' \
-d 'client_secret=YOUR_SERVICE_ACCOUNT_SECRET' \
-d 'grant_type=client_credentials'

JavaScript

const response = await fetch(
'https://ssohml.credsystem.com.br/auth/realms/{realm}/protocol/openid-connect/token',
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: 'YOUR_SERVICE_ACCOUNT_ID',
client_secret: 'YOUR_SERVICE_ACCOUNT_SECRET',
grant_type: 'client_credentials'
})
}
);

const { access_token } = await response.json();
💼 Casos de Uso

Use service account para:

  • Tarefas agendadas
  • Processos em background
  • Integrações backend-to-backend
  • Operações em lote

👤 4. Gerenciamento de Sessão

Buscar Informações da Sessão

Após o login, você pode consultar informações sobre a sessão atual do usuário.

GET {baseUrl}/sessao/info-ext
Authorization: Bearer {token}

Exemplo de Resposta

{
"usuario": {
"cpf": "12345678909",
"nome": "João Silva",
"email": "joao.silva@example.com"
},
"sessao": {
"id": "f3d2e1c0-b9a8-7654-3210",
"dataInicio": "2025-12-03T10:30:00Z",
"dispositivo": {
"id": "device123",
"modelo": "Samsung Galaxy S21"
}
}
}
Endpoint Interno

Para uso interno, existe também: GET {baseUrlInterna}/sessao/info


Buscar Informações por CPF (Service Account)

Com um token de service account, você pode buscar informações de usuário por CPF.

GET {baseUrl}/usuario/sso/info/{cpf}
Authorization: Bearer {token}
APP: nome-do-app

cURL

curl -X GET '{baseUrl}/usuario/sso/info/12345678909' \
-H 'Authorization: Bearer {service-account-token}' \
-H 'APP: meu-app-private-label'

JavaScript

const response = await fetch(
`${baseUrl}/usuario/sso/info/12345678909`,
{
headers: {
'Authorization': `Bearer ${serviceAccountToken}`,
'APP': 'meu-app-private-label'
}
}
);

const userInfo = await response.json();

🔒 Boas Práticas de Segurança

Armazenamento de Tokens

✅ FAZER:

  • Use armazenamento seguro do sistema (Keychain/KeyStore)
  • Criptografe tokens antes de armazenar
  • Limpe tokens ao fazer logout

❌ NÃO FAZER:

  • Armazenar em SharedPreferences/UserDefaults sem criptografia
  • Armazenar em memória volátil
  • Logar tokens em produção

Gestão de Credenciais

// ✅ CORRETO - Backend
const credentials = {
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET
};

// ❌ ERRADO - Frontend
const credentials = {
client_secret: 'hardcoded-secret' // NUNCA FAÇA ISSO!
};

Implementação de Retry

async function loginWithRetry(username, password, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await login(username, password);
return response;
} catch (error) {
if (error.status === 401) {
throw new Error('Credenciais inválidas');
}

if (error.status === 429) {
// Rate limit - aguarde antes de tentar novamente
await sleep(Math.pow(2, attempt) * 1000);
continue;
}

if (error.status >= 500 && attempt < maxRetries) {
// Erro no servidor - tente novamente
await sleep(Math.pow(2, attempt) * 1000);
continue;
}

throw error;
}
}
}

⚠️ Tratamento de Erros

CódigoStatusDescriçãoAção Recomendada
400❌ Bad RequestRequisição inválidaValide os parâmetros enviados
401❌ UnauthorizedCredenciais inválidasVerifique usuário/senha
403❌ ForbiddenAcesso negadoVerifique permissões do cliente
429⚠️ Too Many RequestsRate limit excedidoAguarde e tente novamente
500🔥 Internal Server ErrorErro interno do servidorTente novamente em alguns segundos

Exemplo de Resposta de Erro

401 Unauthorized
{
"error": "invalid_grant",
"error_description": "Invalid user credentials",
"timestamp": "2025-12-03T10:30:00Z"
}

📚 Recursos Relacionados


Última atualização: 03 de Dezembro de 2025