Utilizando o Amazon Cognito para implementar autorização em Lambda
Utilizando o Amazon Cognito para implementar autorização em Lambda
A grande maioria dos sistemas necessitam controlar acesso aos seus recursos. Normalmente, esse controle é realizado por meio de cadastro de usuários que deverão se autenticar antes de poder acessar determinado endpoint de uma API, por exemplo. Essa atividade se torna um pouco repetitiva e envolve questões de segurança e planejamento de como lidar com os dados utilizados nessa tarefa. Para evitar o retrabalho e gasto do tempo com essa atividade, a AWS dispõe do Cognito.
O que é Amazon Cognito?
O Amazon Cognito (AWS Cognito) possibilita criar com facilidade e rapidez o cadastramento, autenticação e controle de acesso de usuários em aplicações Web ou Mobile, de maneira altamente escalável, configurável e segura.
Além disso, também facilita que os usuários possam fazer login utilizando provedores de identidade social, como o Facebook, Amazon e Google, e também provedores de identidade empresarial, como o OpenID Connect. Tudo isso pode ser configurado via o próprio console da AWS ou programaticamente.
Explorando o Amazon Cognito
Para exemplificar o uso do Amazon Cognito, vamos construir uma aplicação simples utilizando o Serverless Framework. Criaremos funções lambda para cadastrar e logar usuários no Cognito. Para, assim, utilizá-lo como autorizador em uma função simples, que retornará uma mensagem de boas-vindas ao usuário
autenticado.
Preparação do ambiente
Antes de começar a codificar, é necessário configurar o CLI da AWS com as credenciais de um usuário IAM, criado via console da plataforma. Também é necessário possuir o Serverless Framework instalado em sua máquina.
Criação do projeto
Vamos criar um projeto utilizando um template pré-configurado para trabalhar com a AWS, Node e TypeScript.
Para isso, basta executar o comando abaixo:
Configuração do projeto
Agora, precisamos configurar nosso projeto para trabalhar com o Amazon Cognito. Para isso, vamos alterar o arquivo serverless.ts na raiz do projeto, e adicionar as configurações necessárias.
Primeiramente, precisamos configurar duas variáveis de ambiente. Então, adicionamos isso no bloco environment, são elas: user_pool_id (que contém o ID do grupo de usuários que será utilizado) e client_id (que define o ID do cliente do Amazon Cognito).
Em seguida, precisamos configurar as permissões do AWS IAM, para que as funções lambda que serão criadas a seguir possam ter acesso aos recursos necessários para se trabalhar com o Cognito. Todas as permissões foram adicionadas dentro do bloco iamRoleStatements.
Por fim, precisamos configurar os recursos necessários para se trabalhar com o Cognito. Dessa forma, adicionamos todas as configurações no bloco resources. Nele, criamos e nomeamos o grupo de usuários e cliente no Amazon Cognito, definimos como será o esquema de dados, políticas de validação de senha, número de horas que um token será válido e outras configurações.
Para isso, adicione as seguintes configurações no arquivo serverless.ts:
Criação da função de cadastro em um grupo de usuários do Cognito
Agora que temos nosso projeto criado e configurado, podemos seguir e criar nossa primeira função lambda. Ela será responsável por realizar o cadastro de um usuário no Cognito:
Primeiramente, obtemos os dados recebidos pelo usuário e os validamos. Em seguida, configuramos um objeto com o e-mail validado, o ID do grupo de usuários e algumas configurações adicionais, como a MessageAction (que aqui está definida com “SUPPRESS” para não enviar e-mail de confirmação para o
usuário cadastrado).
Após registrar o usuário, precisamos também salvar a senha de acesso. Então, criamos um objeto que contém o e-mail do usuário criado, a senha validada e o ID do grupo de usuários. Se tudo ocorrer bem, a resposta conterá o e-mail do usuário cadastrado e um status associado.
Para essa função e as demais que serão implementadas, foram utilizadas três outras funções auxiliares, são elas:
- validateCredentials: é responsável por validar a entrada dos dados fornecidos pelos usuários, conferindo se o e-mail e senha são válidos. Para isso, é verificado se a senha possui pelo menos oito caracteres. E, para validar o e-mail, é utilizada uma biblioteca externa para verificar se segue o padrão esperado. Para instalá-la em seu projeto, basta executar o comando npm i validator ou yarn add validator.
- formatResponse: formata a resposta que será enviada para o usuário, definindo seu código de status, corpo da resposta e outras definições.
- badRequest: devolve um objeto que representa o código de status HTTP, Bad Request. Para obter a implementação dessas funções, basta acessar a pasta src/libs, no repositório, que contém todo o código fonte do projeto acessando o link: https://github.com/ivansimplicio/aws-cognito-example.
Criação da função para realizar login no Cognito
Agora que já podemos realizar o cadastro no grupo de usuários do Cognito, precisamos criar também a função para fazer o login na plataforma. Para, assim, obter o token de acesso para utilizá-lo em funções que estarão protegidas.
Então, criamos a função da seguinte maneira:
Aqui, novamente, obtemos as credenciais informadas pelo usuário e as validamos. Em seguida, criamos um objeto com os dados validados, e as informações necessárias para realizar a busca do usuário, como o ID do grupo a qual ele pertence e o ID do cliente do Cognito. Por fim, chamamos a função adminInitiateAuth,passando o objeto criado para tentar autenticar o usuário.
Caso as credenciais estejam corretas, é devolvido um token de acesso como resposta. Com isso, podemos partir para a próxima etapa.
Utilizando o Cognito como autorizador em uma função Lambda
Agora que já podemos cadastrar os usuários no Cognito e obter um token de acesso por meio da função de login criada, podemos testar nosso autorizador utilizando-o em uma nova função lambda.
Para isso, precisamos configurar nossa função da seguinte maneira:
No bloco authorizer, definimos o autorizador que será utilizado para controlar o acesso a função, que verificará se o token de acesso foi passado na requisição. Nomeamos nosso autorizador de CognitoAuthorizer, e precisamos também passar o ARN do nosso grupo de usuários do Cognito. Sendo assim, referenciamos esse recurso e obtemos o ARN dele utilizando a função “:GetAtt”.
Por fim, definimos no bloco claims, que iremos utilizar o campo e-mail do objeto token decodificado. Para, assim, obter o e-mail do usuário que acesse nossa função.
Com a função devidamente configurada, podemos seguir para sua implementação. Abaixo é mostrada a função criada. Ela basicamente resgata o e-mail do usuário autenticado que a está acessando, exibindo uma mensagem de boas-vindas:
A mensagem será exibida caso o usuário tenha informado um token válido. Caso não seja passado um token, ou o token for inválido, o autorizador não permitirá que o usuário tenha acesso a função hello, devolvendo a mensagem “Unauthorized”.
Realizando o deploy
Agora que temos toda a parte de implementação concluída, podemos enviar nossas funções para a AWS e testar o seu funcionamento. Para realizar o deploy, basta executar o seguinte comando pela sua CLI: serverless deploy.
Após alguns instantes, o envio estará concluído e serão exibidas as URLs para acesso de cada uma das funções implementadas, que poderão ser acessadas e testadas.
Veja também:
Como Configurar Atalhos no Git
Biblioteca de tutoriais da Luby
Conclusão
O AWS Cognito é uma excelente opção para quem busca implementar a autenticação e o controle de acesso em seu sistema Web ou Mobile, uma vez que ele provê:
- Armazenamento de identidades de maneira segura e escalável;
- Federação com provedores de identidades sociais e empresariais;
- Fácil integração com aplicativos;
- E ainda mais diversos outros fatores, como ser altamente configurável (o que possibilita que ele se adapte facilmente a boa parte das aplicações).
Autor: Ivanildo Simplício.