Melhores práticas para Autorização de API

4 Melhores Práticas para Autorização de API

Melhores práticas para Autorização de API
Photo by FlyD / Unsplash

As API's (Interfaces de Programação de Aplicativos) são como portas secretas que permitem que diferentes programas de software conversem. Mas nem todos devem ter as chaves para todas as portas, assim como nem todo software deve ter acesso irrestrito a todas as API's.

Essas API's conectam desde o aplicativo móvel do seu banco até a sua plataforma de mídia social favorita, lidando com dados sensíveis e realizando funções críticas.

Sem protocolos de autorização rigorosos, as APIs podem ser mal utilizadas, levando a violações de dados, interrupções de serviço e perda de confiança do usuário.

Portanto, é aqui que entra a autorização da API.

A autorização da API atua como um porteiro, garantindo que apenas o software correto com a chave correta possa abrir a porta e usar os recursos internos. A autorização efetiva da API vai além da segurança; ela cria uma experiência do usuário perfeita e segura. Ela garante que aplicativos autorizados acessem apenas informações pessoais e que esses aplicativos possam realizar apenas ações dentro de seu escopo permitido.

Se você quiser conferir uma demonstração legal sobre Segurança de API, confira meu Bit Scope.

Compreendendo a Autorização da API

Antes de discutir as melhores práticas de autorização da API, é necessário entender a diferença entre dois conceitos frequentemente confundidos: autorização e autenticação.

  • Autenticação trata da verificação de identidade. É como confirmar a identidade de um usuário por meio de um nome de usuário, senha ou biometria.
  • Autorização trata da concessão de acesso a recursos ou funcionalidades após a confirmação da identidade. Por exemplo, se a autenticação trata de passar pela porta da frente, a autorização determina quais salas e serviços a pessoa pode acessar dentro do prédio.

Melhores Práticas na Autorização de API

Agora que você entende a importância da autorização da API, vamos nos aprofundar em algumas das melhores práticas para aproveitá-la ao máximo.

1. Use Autorização Baseada em Token (JWT, Tokens OAuth)

A autorização baseada em token, especialmente com JWT (JSON Web Tokens) e tokens OAuth, oferece uma maneira segura e eficiente de gerenciar as interações da API. Por exemplo:

  • Tokens permitem autenticação sem estado, o que significa que o servidor não precisa manter um estado de sessão para cada usuário, resultando em melhor escalabilidade.
  • Tokens podem ser transmitidos com segurança por vários meios e são menos suscetíveis a ataques de CSRF do que a autenticação baseada em sessão tradicional.
  • Tokens podem ser usados em diferentes domínios, tornando-os ideais para arquitetura de microsserviços e aplicativos de logon único (SSO).
  • Tokens, especialmente tokens OAuth, podem incluir escopos e permissões, fornecendo controle preciso sobre as ações de um usuário autenticado.

Como Implementar a Autorização Baseada em Token com JWT

Os JWT's geralmente são gerados depois que um usuário é autenticado com sucesso. Eles contêm um payload com informações do usuário e possivelmente suas permissões. Você pode usar bibliotecas como jsonwebtoken no Node.js ou PyJWT no Python para implementar a autorização JWT.

Primeiro, você precisa gerar o token JWT. Veja como fazer isso usando PyJWT:

import jwt
from datetime import datetime, timedelta

secret_key = 'YOUR_SECRET_KEY'
payload = {
    'sub': user_id,
    'iat': datetime.utcnow(),
    'exp': datetime.utcnow() + timedelta(days=1)
}

token = jwt.encode(payload, secret_key, algorithm='HS256')

Em seguida, você precisa validar cada solicitação para decidir se o usuário tem permissão para executar a solicitação. O token geralmente é enviado no cabeçalho de autorização de cada solicitação. O servidor pode decodificar o JWT usando a chave secreta e validá-lo. Se for válido, o servidor processa a solicitação; caso contrário, ele retorna um erro.

from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(name)
SECRET_KEY = "your_secret_key"  # Replace with your secret key

Sample route that requires token-based authorization
@app.route('/protected', methods=['GET'])
def protected():
    token = request.headers.get('Authorization')
    if not token:
        return jsonify({'message': 'Token is missing!'}), 403

    try:
        # Decoding the token
        data = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        # You can use the data in the token as needed, for example:
        # user_id = data['user_id']

    except jwt.ExpiredSignatureError:
        return jsonify({'message': 'Token has expired!'}), 403
    except jwt.InvalidTokenError:
        return jsonify({'message': 'Invalid token!'}), 403

    # Token is valid, process the request
    return jsonify({'message': 'Token is valid! You have access to protected routes.'})

2. Implemente Controle de Acesso Detalhado

O Controle de Acesso Detalhado é uma abordagem de gerenciamento de segurança que oferece controle detalhado sobre as permissões e direitos de acesso de um aplicativo. Ele garante que os usuários ou serviços tenham apenas o acesso necessário, seguindo o princípio do menor privilégio.

Como Implementar o Controle de Acesso Detalhado:

A implementação do controle de acesso detalhado envolve várias etapas:

  • Defina Funções e Permissões: Identifique diferentes funções de usuário em seu sistema e defina as ações específicas de cada função.
  • Use Controle de Acesso Baseado em Função (RBAC): Implemente o RBAC, onde o acesso aos recursos é concedido com base em funções. Cada função é atribuída a permissões específicas.
  • Considere o Controle de Acesso Baseado em Atributos (ABAC): Para cenários mais complexos, o ABAC pode ser usado, onde as decisões de acesso são baseadas em uma combinação de atributos (usuário, recurso, ambiente).

Por exemplo, se você tem uma API em que o acesso difere entre um administrador e um usuário, você pode implementar seus mecanismos de controle de acesso usando componentes independentes que podem ser reutilizados em seu aplicativo.

Por exemplo, você pode aproveitar ferramentas como o Bit para criar um componente de autorizador independente que será responsável por autorizar solicitações de API.

Tudo que você precisa fazer é:

1. Criar um componente Node.js chamado "authorizer" que permite implementar sua lógica de autenticação usando o comando:

bit create node util/authorizer

Se você fizer isso corretamente, verá a saída:

Em seguida, implemente sua lógica de autorizador:

export function authorizer(userId: string) {
 // Implement logic to retrieve the user's role
 if (userId === 'U001') {
   return "admin";
 }
 return "customer"
}

Em seguida, crie um aplicativo Express usando o comando:

bit create express-app api

Você verá a saída:

Em seguida, vamos conectar o autorizador ao aplicativo atualizando o mock-route.ts. Inicialmente, você verá isso:

Vamos adicionar um novo middleware:

Isso garantirá que o componente de autorizador seja executado antes de invocar a lógica de negócios real. Depois de executar sua API, você verá a seguinte saída:

Ao encadear funções, aplicamos o controle de acesso baseado em função. O decorador verifica se a função do usuário corresponde às funções necessárias para o endpoint. Se não corresponder, ele retorna uma mensagem de acesso negado.

E, à medida que você atualiza a lógica do autorizador e atualiza o aplicativo, o servidor CI do Bit - Ripple CI - atualiza automaticamente as alterações em toda a árvore.

Se você quiser conferir essa implementação completa, confira meu Bit Scope.

3. Configure de Forma Segura o Gateway de API

Um Gateway de API atua como uma porta de entrada para todas as solicitações de API, fornecendo um local centralizado para aplicar políticas de segurança e operacionais. Por exemplo, os Gateways de API ajudam com:

  • Segurança Aprimorada: Fornece uma camada adicional de segurança, protegendo contra ameaças como ataques de negação de serviço distribuído (DDoS), acesso não autorizado e abuso de API.
  • Limitação de Taxa e Controle de Vazão: Impede o uso excessivo de API e garante o uso justo entre os usuários.
  • Transformação e Validação de Dados: Garante que os dados recebidos estejam de acordo com os formatos e padrões esperados.

Como Implementar uma Configuração Segura do Gateway de API:

Existem vários provedores de Gateway de API que você pode escolher para o seu aplicativo. Por exemplo, Amazon API Gateway, Kong e Apigee da Google são algumas das plataformas de Gateway de API mais populares.

Se você planeja usar a AWS, pode seguir as etapas em sua documentação para criar facilmente um Gateway de API. No entanto, existem algumas coisas adicionais que você precisa habilitar para garantir que o Gateway de API esteja seguro e eficiente.

  • Configurar Limitação de Taxa: No Console de Gerenciamento da AWS, acesse o Amazon API Gateway, selecione sua API e vá para a seção de Limitação de Vazão na guia Proteger. Lá, você pode definir os limites de taxa e explosão.
  • Habilitar SSL/TLS: Certifique-se de que o nome de domínio personalizado para o Gateway de API esteja associado a um certificado SSL/TLS no AWS Certificate Manager.
  • Implementar Restrições de IP: Use autorizadores AWS Lambda para validar os endereços IP das solicitações recebidas. Depois que a função for implantada, você poderá selecioná-la criando um novo autorizador para o Gateway de API na guia Autorização. Aqui está uma função Lambda de exemplo em Python para restringir IP's:
import json

def lambda_handler(event, context):
    ip_address = event['requestContext']['identity']['sourceIp']
    allowed_ips = ['192.168.1.1']  # List of allowed IPs
    # Add logic here to check if the ip_address is in allowed_ips or not

    if ip_address not in allowed_ips:
        raise Exception('Unauthorized')

    return {
        'principalId': 'user',
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': 'Allow',
                'Resource': event['methodArn']
            }]
        }
    }
  • Habilitar Logs do CloudWatch: No Console de Gerenciamento da AWS, vá para as configurações do seu Gateway de API. Na seção Configurações do CloudWatch, marque a opção Habilitar Logs do CloudWatch. Defina o nível de log como INFO para registrar todas as solicitações e respostas ou ERROR para registrar apenas respostas de erro.

4. Criptografe Dados Sensíveis em Trânsito e em Repouso

A criptografia de dados sensíveis em trânsito e em repouso é uma prática fundamental de segurança para proteger dados contra acesso não autorizado e violações. A criptografia em trânsito protege os dados enquanto eles se movem entre clientes e servidores, enquanto a criptografia em repouso protege os dados armazenados em disco ou banco de dados.

Como Implementar a Criptografia em Trânsito

Se você estiver usando seu próprio servidor da web, deverá configurar e gerenciar manualmente os certificados SSL/TLS. Primeiro, você precisa obter certificados de uma Autoridade de Certificação (CA) confiável, como Let's Encrypt, DigiCert, GoDaddy, etc. Em seguida, configure seu servidor para usar a CA. Por exemplo, aqui está como configurar o SSL com o Nginx:

  • Modifique o arquivo de configuração do Nginx (geralmente encontrado em /etc/nginx/nginx.conf ou /etc/nginx/sites-available/seu_site).
  • Adicione as configurações SSL no bloco do servidor:
server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /path/to/your/fullchain.pem; # Path to your fullchain.pem from CA
    ssl_certificate_key /path/to/your/privkey.pem; # Path to your private key from CA

    # Strong encryption settings (consider using recommendations from Mozilla's SSL Configuration Generator)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256...';
    
    # Other server configurations...
}

Se você usa um serviço em nuvem, eles oferecem serviços totalmente gerenciados para lidar com SSL/TLS. Por exemplo, você pode usar o AWS Certificate Manager para serviços hospedados na AWS.

Como Implementar a Criptografia em Repouso

Você pode implementar a criptografia em repouso no nível do banco de dados, no nível do aplicativo ou usando ferramentas baseadas em nuvem.

  • Criptografia no Nível do Banco de Dados: Muitos bancos de dados modernos oferecem recursos de criptografia integrados. Por exemplo:
  • SQL Server: Criptografia Transparente de Dados.
  • MySQL: Criptografia de Espaço de Tabela InnoDB.
  • MongoDB: Motor de Armazenamento Criptografado.
  • Criptografia no Nível do Aplicativo: A criptografia no nível do aplicativo deve ser usada com dados altamente sensíveis para criptografá-los antes mesmo de serem armazenados no banco de dados. Você pode usar bibliotecas como cryptography para isso:
from cryptography.fernet import Fernet

# Generate a key
key = Fernet.generate_key()
cipher_suite = Fernet(key)

# Encrypt data
encrypted_data = cipher_suite.encrypt(b"Sensitive Data")
# Decrypt data
decrypted_data = cipher_suite.decrypt(encrypted_data)

Conclusão

A autorização robusta da API é crucial para proteger ativos digitais e manter a confiança do usuário. Ao implementar as melhores práticas discutidas aqui, os desenvolvedores podem melhorar significativamente a segurança da API de aplicativos, garantindo conformidade e proteção contra várias ameaças cibernéticas.


Este é um artigo traduzido. O artigo original pode ser lido no link abaixo.

Best-Practices for API Authorization
4 Best Practices for API Authorization