Consumindo a API em C# / .NET v3
Um client HTTP como qualquer outro: app desktop, serviço Windows, mobile .NET MAUI, integração interna. A API não é exclusiva de launcher.
Na prática você tem dois padrões de Bearer:
- Token de login — usuário autentica em
/api/logine recebemcrm_… - Token de serviço — você define
$myTokenno PHP e o client envia o mesmo valor; o servidor lê comrequest()->bearer_token()
Token de serviço
Útil para endpoints de status, sync ou jobs sem login de pessoa.
PHP (API)
$myToken = config('api.service_token');
public function status()
{
$token = request()->bearer_token();
if (!$token || !hash_equals((string) $myToken, (string) $token)) {
return request()->json(['success' => false, 'error' => 'Unauthorized'], 401);
}
return request()->json(['success' => true, 'version' => '2.0.0']);
}C# (client)
var myToken = "xxxxx-seu-segredo";
using var client = new HttpClient {BaseAddress = new Uri("https://seu-site.com/")};
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", myToken);
var res = await client.GetAsync("api/status");
var json = await res.Content.ReadAsStringAsync();💡Mesma API de leitura
Não importa se o Bearer veio do
/api/login ou do seu $myToken: no servidor você sempre usa request()->bearer_token() para extrair o valor limpo (sem o prefixo Bearer ).Detalhes: Autenticação → Token de serviço.
Login de conta + Bearer (mcrm_…)
HttpClient
using System.Net.Http.Headers;
using System.Net.Http.Json;
public sealed class MucrmApiClient
{
private readonly HttpClient _http;
public MucrmApiClient(string baseUrl)
{
_http = new HttpClient {BaseAddress = new Uri(baseUrl.TrimEnd('/') + "/")};
_http.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> LoginAsync(string username, string password, CancellationToken ct = default)
{
var res = await _http.PostAsJsonAsync("api/login", new {username, password}, ct);
var body = await res.Content.ReadFromJsonAsync<LoginResponse>(cancellationToken: ct)
?? throw new InvalidOperationException("Resposta vazia");
if (!res.IsSuccessStatusCode || !body.Success)
throw new Exception(body.Error ?? $"HTTP {(int)res.StatusCode}");
_http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", body.Token);
return body.Token;
}
public async Task<string> MeAsync(CancellationToken ct = default)
{
var res = await _http.PostAsync("api/me", content: null, ct);
res.EnsureSuccessStatusCode();
return await res.Content.ReadAsStringAsync(ct);
}
public async Task LogoutAsync(CancellationToken ct = default)
{
var res = await _http.PostAsync("api/logout", null, ct);
res.EnsureSuccessStatusCode();
_http.DefaultRequestHeaders.Authorization = null;
}
private sealed record LoginResponse(bool Success, string? Token, string? Error, int? Code);
}Uso
var api = new MucrmApiClient("https://seu-site.com");
await api.LoginAsync(txtUser.Text, txtPass.Text);
var meJson = await api.MeAsync();💡Secure storage
Não grave o Bearer em texto plano no disco. Prefira DPAPI / Credential Manager / memória do processo.
Tratando 422
if ((int)response.StatusCode == 422)
{
var err = await response.Content.ReadFromJsonAsync<ValidationEnvelope>();
// err.Errors["password"]
}
record ValidationEnvelope(string Message, Dictionary<string, string> Errors);withoutCsrf
Clients HTTP (app, bot, SPA, desktop) não enviam CSRF de sessão. O grupo routes/api.php já usa 'withoutCsrf' => true. Veja Roteamento.
Próximo: Node.js · JavaScript.