v4 Atualização da v4 disponível — framework refeito do zero. Ver novidades

Docs
Voltar ao blog
API / Backend

15 de August de 2026

Como Criar Autenticação de API via Bearer Token e Estruturar Respostas com HttpData na MuCRM

Aprenda o fluxo completo de autenticação via API na MuCRM: rotas com rate limit, validação, criação de Bearer Tokens e formatação limpa com HttpData e relacionamentos aninhados.

Como Criar Autenticação de API via Bearer Token e Estruturar Respostas com HttpData

Criar APIs seguras e padronizadas é essencial para conectar launchers de jogos, bots do Discord, painéis administrativos, aplicações web e outros sistemas externos.

Prefere em vídeo? Este tutorial também está disponível no nosso canal oficial no YouTube.

Neste tutorial, você vai aprender a implementar o ciclo completo de autenticação via Bearer Token, incluindo:

  • Proteção contra tentativas excessivas com RateLimiter.
  • Controle de acesso às rotas através de Middleware.
  • Autenticação utilizando Bearer Token.
  • Criação e revogação de tokens.
  • Padronização das respostas utilizando HttpData.
  • Transformação de relacionamentos em estruturas JSON.
  • Consumo da API por aplicações externas.

1. Definindo as Rotas da API

As rotas de API devem desativar a verificação de CSRF, já que não são baseadas em formulários web tradicionais.

Também podemos separar as rotas públicas das rotas que exigem autenticação.

No arquivo de rotas da aplicação:

<?php

/**
 * Rotas de API.
 */

use MUCRM\Engine\Support\Facades\Router;
use MUCRM\Http\Controllers\Api\AuthController;

Router::group([
    'prefix' => 'api',
    'withoutCsrf' => true
], function () {

    /**
     * Rota pública de autenticação.
     */
    Router::post('/login', [
        AuthController::class,
        'login'
    ]);

    /**
     * Rotas protegidas por autenticação.
     */
    Router::group([
        'middleware' => ['auth:api']
    ], function () {

        Router::post('/me', [
            AuthController::class,
            'me'
        ]);

        Router::post('/logout', [
            AuthController::class,
            'logout'
        ]);
    });
});

Rotas disponíveis

Método Endpoint Autenticação
POST /api/login Não
POST /api/me Bearer Token
POST /api/logout Bearer Token

O fluxo de autenticação funciona da seguinte maneira:

Cliente
   │
   │ POST /api/login
   ▼
AuthController
   │
   ├── Valida credenciais
   ├── Verifica RateLimiter
   ├── Localiza usuário
   └── Gera Bearer Token
           │
           ▼
      Cliente recebe token
           │
           │ Authorization: Bearer TOKEN
           ▼
      Middleware auth:api
           │
           ▼
      Endpoint protegido

2. Estruturando os Dados com HttpData

A classe HttpData é responsável por controlar quais informações serão expostas pela API.

Em vez de enviar diretamente todos os atributos de um Model para o cliente, criamos classes específicas para transformar os dados em uma estrutura apropriada para respostas HTTP.

Isso permite:

  • Controlar os campos expostos.
  • Renomear propriedades.
  • Esconder informações internas.
  • Serializar relacionamentos.
  • Criar estruturas JSON consistentes.
  • Reutilizar os mesmos Data Layers em diferentes endpoints.

A estrutura poderá ficar assim:

app/
└── Http/
    └── Data/
        ├── GuildData.php
        ├── CharacterData.php
        └── UserData.php

2.1. GuildData

Crie o arquivo:

app/Http/Data/GuildData.php
<?php

namespace MUCRM\Http\Data;

use MUCRM\Engine\Http\Data as HttpData;

class GuildData extends HttpData
{
    public function toArray(): array
    {
        return [
            'name'  => $this->G_Name,
            'mark'  => $this->G_Mark,
            'score' => $this->G_Score,
        ];
    }
}

A classe transforma os dados da Guild em uma estrutura mais limpa para a API.

Por exemplo:

{
    "name": "DarkKnights",
    "mark": "ABC123",
    "score": 12500
}

2.2. CharacterData

Agora podemos criar o Data responsável pelos personagens.

Crie:

app/Http/Data/CharacterData.php
<?php

namespace MUCRM\Http\Data;

use MUCRM\Engine\Http\Data as HttpData;

class CharacterData extends HttpData
{
    public function toArray(): array
    {
        return array_merge([
            'name'  => $this->Name,
            'level' => $this->cLevel,
            'class' => $this->Class,
        ], $this->mergeRelation(
            'guild',
            GuildData::class
        ));
    }
}

Aqui utilizamos:

$this->mergeRelation(
    'guild',
    GuildData::class
)

Isso permite que o relacionamento guild seja transformado utilizando GuildData.

Assim, o personagem pode ser retornado juntamente com os dados da Guild.


2.3. UserData

Por último, vamos criar o Data responsável pelo usuário.

Crie:

app/Http/Data/UserData.php
<?php

namespace MUCRM\Http\Data;

use MUCRM\Engine\Http\Data as HttpData;

class UserData extends HttpData
{
    public function toArray(): array
    {
        return array_merge([
            'login' => $this->memb___id,
        ], $this->mergeRelation(
            'characters',
            CharacterData::class
        ));
    }
}

Agora temos uma cadeia de transformação:

UserData
   │
   └── characters
          │
          └── CharacterData
                  │
                  └── guild
                         │
                         └── GuildData

Isso permite construir respostas complexas sem precisar montar manualmente todo o JSON dentro do Controller.


3. Criando o AuthController

Agora vamos criar o Controller responsável pela autenticação da API.

Crie:

app/Http/Controllers/Api/AuthController.php
<?php

namespace MUCRM\Http\Controllers\Api;

use MUCRM\Engine\Support\RateLimiter;
use MUCRM\Engine\Support\Request;
use MUCRM\Http\Controllers\Controller;
use MUCRM\Http\Data\UserData;
use MUCRM\Models\User;

/**
 * Autenticação da API utilizando Bearer Token.
 */
class AuthController extends Controller
{
    /**
     * Login da API.
     *
     * POST /api/login
     *
     * Body:
     * username
     * password
     */
    public function login(Request $request)
    {
        $rateLimiter = new RateLimiter();

        $key = 'api_login_attempts:' . $request->ip();

        /**
         * Limita a quantidade de tentativas
         * de login por IP.
         */
        if ($rateLimiter->tooManyAttempts($key, 5)) {

            $seconds = $rateLimiter->availableIn($key);

            return $request->json([
                'success' => false,
                'code'    => 429,
                'error'   => 'Muitas tentativas. Tente novamente em ' . $seconds . ' segundos.',
            ], 429);
        }

        /**
         * Validação dos dados enviados.
         */
        $credentials = $request->validate([
            'username' => 'required|string|min:4|max:10',
            'password' => 'required|string|max:10',
        ], [
            'username.required' => 'Informe seu login.',
            'password.required' => 'A senha é obrigatória.',
        ]);

        /**
         * Busca o usuário.
         */
        $user = User::where(
            'memb___id',
            $credentials['username']
        )
        ->where(
            'memb__pwd',
            $credentials['password']
        )
        ->first();

        /**
         * Credenciais inválidas.
         */
        if (!$user) {

            $rateLimiter->hit($key, 2);

            return $request->json([
                'success' => false,
                'code'    => 401,
                'error'   => 'Usuário ou senha incorretos.',
            ], 401);
        }

        /**
         * Verifica se a conta está bloqueada.
         */
        if (((int) ($user->bloc_code ?? 0)) === 1) {

            $rateLimiter->hit($key, 2);

            return $request->json([
                'success' => false,
                'code'    => 403,
                'error'   => 'Conta bloqueada.',
            ], 403);
        }

        /**
         * Login realizado com sucesso.
         *
         * Limpa as tentativas anteriores.
         */
        $rateLimiter->clear($key);

        /**
         * Gera o Bearer Token.
         */
        $token = $user->createLoginToken()->plainTextToken;

        return $request->json([
            'success' => true,
            'token'   => $token,
        ]);
    }

    /**
     * Retorna o usuário autenticado.
     *
     * POST /api/me
     *
     * Middleware:
     * auth:api
     */
    public function me(Request $request)
    {
        $user = $request->user();

        $user->load('characters');

        return $request->json([
            'success' => true,
            'user'    => UserData::make($user),
        ]);
    }

    /**
     * Logout da API.
     *
     * POST /api/logout
     *
     * Middleware:
     * auth:api
     */
    public function logout(Request $request)
    {
        $request->user()->logout();

        return $request->json([
            'success' => true,
        ]);
    }
}

4. Entendendo o RateLimiter

O RateLimiter protege o endpoint de login contra tentativas excessivas.

Primeiro criamos uma chave baseada no IP:

$key = 'api_login_attempts:' . $request->ip();

Depois verificamos se o limite foi atingido:

if ($rateLimiter->tooManyAttempts($key, 5)) {
    // ...
}

Neste exemplo, o limite é de 5 tentativas.

Quando o limite é atingido, podemos descobrir quanto tempo falta para que novas tentativas sejam permitidas:

$seconds = $rateLimiter->availableIn($key);

Quando o usuário informa credenciais incorretas, registramos uma nova tentativa:

$rateLimiter->hit($key, 2);

Após um login bem-sucedido, removemos o controle daquele IP:

$rateLimiter->clear($key);

5. Gerando o Bearer Token

Depois que as credenciais são validadas, o token é criado através do usuário:

$token = $user->createLoginToken()->plainTextToken;

Esse token deve ser enviado ao cliente.

A resposta será:

{
    "success": true,
    "token": "1|a8f9c2e4b7...plainTextToken"
}

O cliente deve armazenar o token de maneira segura.


6. Consumindo a API na Prática

6.1. Realizando o Login

Faça uma requisição:

POST /api/login

Envie os dados em JSON:

{
    "username": "meuusuario",
    "password": "minhasenha"
}

Em caso de sucesso:

{
    "success": true,
    "token": "1|a8f9c2e4b7...plainTextToken"
}

Guarde o token retornado para realizar as próximas requisições autenticadas.


7. Consultando o Usuário Autenticado

Agora podemos utilizar:

POST /api/me

Como essa rota está dentro do grupo:

'middleware' => ['auth:api']

ela exige um Bearer Token válido.

O Header HTTP deve conter:

Authorization: Bearer 1|a8f9c2e4b7...plainTextToken

A requisição será processada pelo Middleware de autenticação antes de chegar ao Controller.


7.1. Resposta

O UserData será responsável pela transformação do usuário.

Exemplo:

{
    "success": true,
    "user": {
        "login": "meuusuario",
        "characters": [
            {
                "name": "DragonKnight",
                "level": 400,
                "class": 1
            }
        ]
    }
}

Caso o relacionamento de Guild também esteja carregado, o CharacterData poderá incluir os dados transformados pelo GuildData.


8. Fazendo Logout

Para revogar o token utilizado atualmente, envie:

POST /api/logout

Com o Header:

Authorization: Bearer 1|a8f9c2e4b7...plainTextToken

O Controller executará:

$request->user()->logout();

E retornará:

{
    "success": true
}

9. Estrutura Final

Ao finalizar o tutorial, a estrutura relacionada à API ficará semelhante a:

app/
├── Http/
│   ├── Controllers/
│   │   ├── Api/
│   │   │   └── AuthController.php
│   │   │
│   │   └── Controller.php
│   │
│   └── Data/
│       ├── GuildData.php
│       ├── CharacterData.php
│       └── UserData.php
│
└── Models/
    └── User.php

E as rotas:

/api/login
/api/me
/api/logout

10. Fluxo Completo da Autenticação

A arquitetura completa pode ser visualizada assim:

                    CLIENTE
                       │
                       │
                       ▼
              POST /api/login
                       │
                       ▼
               AuthController
                       │
              ┌────────┴────────┐
              │                 │
              ▼                 ▼
        RateLimiter          Validação
              │                 │
              └────────┬────────┘
                       │
                       ▼
                  User Model
                       │
                       ▼
                Credenciais OK?
                  │          │
                 NÃO        SIM
                  │          │
                  ▼          ▼
              401/403    Bearer Token
                             │
                             ▼
                           CLIENTE
                             │
                             │ Authorization:
                             │ Bearer TOKEN
                             ▼
                       Middleware
                        auth:api
                             │
                             ▼
                    Endpoint protegido
                             │
                             ▼
                       Controller
                             │
                             ▼
                         HttpData
                             │
                             ▼
                       JSON Response

Conclusão

Com o sistema de autenticação via Bearer Token, o RateLimiter, o Middleware auth:api e a camada HttpData, a API da MuCRM possui uma estrutura organizada para atender diferentes aplicações.

Essa arquitetura permite que a mesma API seja consumida por:

  • Launchers.
  • Bots do Discord.
  • Sites externos.
  • Dashboards.
  • Aplicações desktop.
  • Aplicações mobile.
  • Outros serviços integrados.

O ponto principal é manter cada responsabilidade separada:

Router
  ↓
Middleware
  ↓
Controller
  ↓
Model
  ↓
HttpData
  ↓
JSON

Dessa forma, a API permanece organizada, segura e fácil de expandir conforme novos endpoints forem adicionados à framework.

Pronto para colocar o servidor no ar?

Licença Master a partir de R$ 24,99/mês.

Ver planos

Presente exclusivo

7 dias grátis

Crie sua conta agora e ganhe acesso completo por 7 dias.

Ao criar sua conta, você concorda com nossos Termos e Políticas.