Introdução
Uma aplicação de pedidos precisa de uma forma de autenticar usuários. Você criará um diretório de usuários e um cliente público de aplicação, entrará com um usuário sintético, validará os tokens emitidos e renovará a sessão antes da limpeza.
Conclua primeiro Construa e Valide uma API de Pedidos. Este ambiente novo fornece seu próprio backend público, entradas temporárias de login e um exemplo de validação de tokens. Mantenha os arquivos de senhas e tokens privados.
Relação com as certificações
| Certificação | Tarefa do exame | Prática |
|---|---|---|
| Solutions Architect – Associate (SAA-C03) | Tarefa 1.2 | Login Cognito, validação de tokens e renovação de sessão. |
| Developer – Associate (DVA-C02) | Tarefa 2.1 | Login Cognito, validação de tokens e renovação de sessão. |
| Security – Specialty (SCS-C03) | Tarefa 4.1 | Prática dos fundamentos: Login Cognito, validação de tokens e renovação de sessão. |
Visão geral do laboratório

Crie o Diretório de Usuários da Aplicação
Nesta etapa, você estabelecerá um pool de usuários, um cliente público de aplicação e um usuário sintético confirmado.
Entre no diretório de trabalho e use umask 077 para que arquivos recém-criados sejam acessíveis apenas ao seu usuário. Isso afeta as permissões de arquivos, não as regras de autorização da API:
cd /home/labex/project
umask 077
Um pool de usuários Cognito é o diretório de usuários da sua aplicação. Seus usuários entram na aplicação; sua identidade IAM preparada da CLI administra os recursos de nuvem. Observe AWS View na parte superior para comparar esses recursos nativos.
Crie o pool de usuários do laboratório. $(...) armazena o ID retornado do pool para os comandos nativos seguintes:
POOL_ID=$(aws cognito-idp create-user-pool \
--pool-name labex-a04-users \
--query UserPool.Id \
--output text)
echo "$POOL_ID"
Registre seu ID; > grava o valor no arquivo de inventário:
printf '%s\n' "$POOL_ID" > pool-id.txt
Um cliente de aplicação (app client) identifica a aplicação que autentica usuários por meio deste pool. Uma aplicação pública não consegue manter um segredo de cliente confidencial. Crie este cliente sem segredo, permitindo o fluxo de nome de usuário/senha e o fluxo de token de renovação usados neste passo a passo:
CLIENT_ID=$(aws cognito-idp create-user-pool-client \
--user-pool-id "$POOL_ID" \
--client-name orders-client \
--no-generate-secret \
--explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_REFRESH_TOKEN_AUTH \
--query UserPoolClient.ClientId \
--output text)
echo "$CLIENT_ID"
printf '%s\n' "$CLIENT_ID" > client-id.txt
Inspecione a configuração segura do cliente sem solicitar valores secretos:
aws cognito-idp describe-user-pool-client \
--user-pool-id "$POOL_ID" \
--client-id "$CLIENT_ID" \
--query '{Name:UserPoolClient.ClientName,Flows:UserPoolClient.ExplicitAuthFlows}'
Crie o usuário de demonstração com o envio de e-mail suprimido. Esta é uma ação de provisionamento do administrador, distinta do login posterior do usuário:
aws cognito-idp admin-create-user \
--user-pool-id "$POOL_ID" \
--username labex-demo \
--message-action SUPPRESS \
--user-attributes Name=email,Value=demo@example.test \
--query '{Username:User.Username,Status:User.UserStatus}'
O status inicial é FORCE_CHANGE_PASSWORD. Apenas para este usuário temporário de teste, aplique pela CLI o arquivo fornecido de entrada de senha permanente. O arquivo tem os campos Username, Password e Permanent; a sintaxe file:// os lê sem imprimir a senha:
aws cognito-idp admin-set-user-password \
--user-pool-id "$POOL_ID" \
--cli-input-json file://demo-password.json
Inspecione apenas o status seguro do usuário:
aws cognito-idp admin-get-user \
--user-pool-id "$POOL_ID" \
--username labex-demo \
--query '{Username:Username,Status:UserStatus,Enabled:Enabled}'
Espere labex-demo, CONFIRMED e true. No AWS View, compare o ID do pool do laboratório, orders-client, sua ausência de segredo de cliente e o usuário confirmado e habilitado. Exemplo do estado nativo real do pool/cliente/usuário:

O pool não relacionado labex-a04-reference permanece vazio. Nenhum token de usuário foi solicitado ainda.
Entre e Leia a Identidade da Aplicação
Nesta etapa, você obterá tokens reais para o usuário confirmado e observará a rejeição de uma senha incorreta.
InitiateAuth com USER_PASSWORD_AUTH autentica o nome de usuário e a senha da aplicação. Ele não autoriza o usuário por meio da identidade IAM de administrador da sua CLI. O sign-in.json fornecido contém os parâmetros sintéticos de nome de usuário/senha para esta demonstração.
Armazene apenas AuthenticationResult em um arquivo privado. Não use cat nesta resposta; ela contém tokens bearer:
aws cognito-idp initiate-auth --client-id "$CLIENT_ID" --auth-flow USER_PASSWORD_AUTH --auth-parameters file://sign-in.json --query AuthenticationResult --output json > tokens.json
Mostre apenas os campos não secretos da resposta com jq. A expressão de presença de tokens retorna um booleano em vez dos valores dos tokens:
jq '{TokenType,ExpiresIn,TokensPresent:(has("AccessToken") and has("IdToken") and has("RefreshToken"))}' tokens.json
Espere Bearer, uma duração positiva de expiração e TokensPresent: true. O token de acesso autoriza solicitações apropriadas de usuário/API, o token de ID transporta informações de identidade para a aplicação e o token de renovação (refresh token) pode obter novos tokens de acesso e ID. Eles têm finalidades diferentes e não são intercambiáveis.
Extraia os tokens de acesso e ID para arquivos privados de transporte. jq -r grava strings sem aspas, e o redirecionamento as mantém fora do terminal:
jq -r '.AccessToken' tokens.json > access-token.txt
jq -r '.IdToken' tokens.json > id-token.txt
GetUser autentica com o token de acesso. Solicite apenas o nome de usuário na saída:
aws cognito-idp get-user \
--access-token "$(cat access-token.txt)" \
--query Username \
--output text
Espere labex-demo. Esta é uma resposta ativa do Cognito ao token emitido, não uma prova inferida apenas de um arquivo JSON local.
Teste os parâmetros fornecidos de senha incorreta, redirecionando qualquer resposta inesperada de tokens para um arquivo privado separado:
aws cognito-idp initiate-auth --client-id "$CLIENT_ID" --auth-flow USER_PASSWORD_AUTH --auth-parameters file://wrong-sign-in.json --query AuthenticationResult --output json > rejected-login.json
Espere NotAuthorizedException: Incorrect username or password. O comando termina intencionalmente com código diferente de zero; continue para a próxima etapa após ler essa rejeição exata. Um erro de conexão ou de transporte da autenticação não é evidência de rejeição por senha errada. Não sobrescreva seus tokens válidos com este resultado de falha. A verificação automática da etapa valida de forma independente os tokens emitidos e o resultado ativo de GetUser; observe manualmente o erro específico de senha errada.

Valide Tokens Assinados e Renove a Sessão
Nesta etapa, você verificará a assinatura do token e seu destinatário pretendido, renovará a sessão e distinguirá login de proteção de rotas da API.
Um JWT contém dados codificados de cabeçalho e claims, além de uma assinatura. Apenas decodificá-lo não comprova quem o emitiu. JWKS é o conjunto de chaves públicas de assinatura do emissor; RS256 usa uma assinatura RSA que pode ser verificada com essas chaves públicas.
Leia o exemplo comum fornecido de validação da aplicação; ele não contém senhas nem tokens literais:
cat verify_tokens.py
O exemplo recupera o JWKS público do seu pool em seu endpoint preparado do ambiente de trabalho, verifica RS256 e o ID da chave e confere emissor, horário atual, token_use e cliente de aplicação. O emissor assinado usa a identidade do pool Cognito. O token de acesso identifica o cliente com client_id; o token de ID usa aud. Execute-o com o arquivo de tokens salvo e os IDs reais de pool/cliente:
/home/labex/project/client-venv/bin/python verify_tokens.py tokens.json "$POOL_ID" "$CLIENT_ID"
Espere resumos seguros para access e id, cada um com RS256 e current_time_valid: true. Ele também altera um byte da assinatura em memória e confirma a rejeição antes de aceitar as claims; nenhum token adulterado é salvo. O escopo aws.cognito.signin.user.admin do token de acesso permite operações de autoatendimento do usuário do Cognito. Esse escopo não é acesso de administrador AWS, uma regra de propriedade de pedidos nem um escopo de negócio personalizado.
Crie parâmetros privados de renovação a partir do token de renovação original. Isso grava em um arquivo e não expõe o valor:
jq '{REFRESH_TOKEN:.RefreshToken}' tokens.json > refresh-parameters.json
Obtenha novos tokens de acesso e ID sem enviar novamente a senha do usuário:
aws cognito-idp initiate-auth --client-id "$CLIENT_ID" --auth-flow REFRESH_TOKEN_AUTH --auth-parameters file://refresh-parameters.json --query AuthenticationResult --output json > refreshed.json
Valide os tokens renovados pelas mesmas verificações de chave pública e claims:
/home/labex/project/client-venv/bin/python verify_tokens.py refreshed.json "$POOL_ID" "$CLIENT_ID"
Espere resumos válidos de acesso/ID para o mesmo pool e cliente. A resposta de renovação não precisa conter outro token de renovação; preserve a resposta privada original até a limpeza.
O login sozinho não altera a API pública preparada. Encontre seu ID gerado e envie uma solicitação pública de saúde sem um token bearer:
API_ID=$(aws apigatewayv2 get-apis \
--query "Items[?Name=='labex-a04'].ApiId | [0]" \
--output text)
echo "$API_ID"
printf '%s\n' "$API_ID" > api-id.txt
curl -i "http://127.0.0.1:8081/api/$API_ID/health"
Espere HTTP 200 e healthy: true. O AWS View ainda mostra autorização NONE para todas as rotas e nenhum item de pedido. A autenticação do usuário teve sucesso, mas a API ainda não exigiu um token. A próxima unidade adiciona autorização JWT às rotas; um token válido ainda não estabelece automaticamente a propriedade de um pedido específico.
A renovação continua a sessão autenticada para o mesmo cliente de aplicação. Ela não altera as configurações de autorização de uma rota da API nem concede acesso a um pedido. Separe essas decisões ao comparar os resumos de identidade renovados com a resposta de saúde que continua pública.
Remova os Recursos de Login e da API
Nesta etapa, você removerá os recursos de login do laboratório e os recursos fornecidos do backend, preservando o pool, a tabela e os logs de referência não relacionados.
Seu inventário é labex-a04-users de pool-id.txt, orders-client de client-id.txt, o usuário labex-demo, o ID de API em api-id.txt, labex-a04-orders-api, seu grupo de logs da função, labex-a04-orders e a política OrdersData da função IAM. Exclua apenas esses recursos nomeados.
Remova o usuário sintético, depois o cliente de aplicação e o pool do laboratório:
aws cognito-idp admin-delete-user --user-pool-id "$POOL_ID" --username labex-demo
aws cognito-idp delete-user-pool-client --user-pool-id "$POOL_ID" --client-id "$CLIENT_ID"
aws cognito-idp delete-user-pool --user-pool-id "$POOL_ID"
Exclua a API funcional preparada e seus recursos de backend do laboratório:
aws apigatewayv2 delete-api --api-id "$API_ID"
aws lambda delete-function --function-name labex-a04-orders-api
aws logs delete-log-group --log-group-name /aws/lambda/labex-a04-orders-api
aws dynamodb delete-table \
--table-name labex-a04-orders \
--query TableDescription.TableName \
--output text
aws iam delete-role-policy --role-name labex-a04-execution --policy-name OrdersData
Consulte os inventários nativos com sucesso; falhas de transporte não comprovam a ausência:
aws cognito-idp list-user-pools --max-results 60 --query 'UserPools[].Name'
aws apigatewayv2 get-apis --query 'Items[].Name'
aws lambda list-functions --query 'Functions[].FunctionName'
aws dynamodb list-tables --query TableNames
Espere apenas o pool e a tabela de referência, com listas vazias de APIs/funções. O AWS View deve mostrar o mesmo estado e preservar o item de referência e INFO platform reference keep unchanged. A função de execução preparada mantém FunctionLogs.
Remova seus arquivos privados de autenticação, incluindo as entradas fornecidas de senhas sintéticas. rm -f exclui apenas os arquivos locais explicitamente listados:
rm -f tokens.json access-token.txt id-token.txt refreshed.json refresh-parameters.json rejected-login.json sign-in.json wrong-sign-in.json demo-password.json
Remover arquivos locais sozinho não é revogação de sessão no servidor. Aqui, o usuário sintético, o cliente e o pool também foram excluídos; este laboratório não afirma fornecer um mecanismo geral de logout ou revogação JWT. Mantenha os recursos de referência não relacionados até a limpeza do autor e o encerramento da VM.
Resumo
Você criou um diretório de usuários da aplicação e um cliente público de aplicação, provisionou um usuário sintético, entrou e observou uma rejeição por senha errada. Você verificou assinaturas RS256 reais e claims de emissor/cliente/horário/tipo, leu a identidade ativa do usuário e renovou tokens de acesso e ID. Você distinguiu usuários Cognito de identidades IAM e login de autorização da API e removeu os recursos do laboratório e arquivos privados, preservando as referências.
Para aprofundar o tema, consulte a documentação da AWS: Finalidades dos tokens do grupo de usuários; Assinaturas JWT e validação de declarações; Renovação de sessão e fluxos de tokens de atualização.



