Skip to content

Basic Auth Generator — PHP source

Build HTTP Basic Access Authentication headers from a username and password, or decode an existing Authorization header back to its credentials. UTF-8 safe and fully client-side, with a shareable link.

This is the PHP implementation — the same logic the interactive tool runs, in a shareable, citable form.

<?php
/**
 * basic-auth-generator — HTTP Basic-Auth header encode/decode.
 *
 * Language: PHP (8.1+, standard library only)
 * Source:   CosmoDev polyglot showcase port of the Basic Auth Generator tool,
 *           ported from src/lib/basic-auth.ts (the canonical TypeScript
 *           implementation) and kept in lock-step with cli/basic-auth-generator.
 * License:  display source — part of CosmoDev's polyglot tool pages.
 *
 * Design goals:
 *   - Pure + deterministic; never throws (parse returns null on malformed input).
 *   - Functionally equivalent to the TS reference + Go twin: same inputs ->
 *     same outputs, same reject behavior on malformed headers.
 *   - Self-contained: stdlib only (no Composer packages).
 *
 * PHP ships base64_encode / base64_decode in the standard library, so we use
 * the real RFC 4648 path. base64_decode($s, $strict=true) rejects any
 * character outside the alphabet (returning false), exactly like Go's
 * base64.StdEncoding.DecodeString and the TS b64decode validator.
 */

declare(strict_types=1);

/**
 * A parsed username/password pair. Mirrors the Go twin's `Credentials` struct
 * and the TS `BasicAuthCredentials` interface. Readonly so the parsed result
 * can't be mutated after construction (PHP 8.1 readonly properties).
 */
final class BasicAuthCredentials
{
    public function __construct(
        public readonly string $user,
        public readonly string $pass,
    ) {
    }
}

/**
 * Build an HTTP Basic-Auth header value: `Basic <base64(user:pass)>`.
 *
 * Mirrors buildBasicAuth() in the TS source and BuildHeader() in the Go twin.
 * base64_encode operates on the raw byte string; in PHP strings are byte
 * arrays, so multibyte credentials encode correctly as long as the input is
 * already UTF-8 (the default for this tool's source).
 */
function build_basic_auth(string $user, string $pass): string
{
    return 'Basic ' . base64_encode($user . ':' . $pass);
}

/**
 * Parse a `Basic <token>` header back into credentials, or null if the header
 * is malformed or the credentials have no colon separator.
 *
 * Logic mirrors ParseHeader() in the Go twin exactly: trim the header, require
 * a case-insensitive `basic ` prefix, trim the remaining token, base64-decode
 * it (rejecting invalid characters via strict mode), then split on the FIRST
 * colon so a password containing colons round-trips.
 */
function parse_basic_auth(string $header): ?BasicAuthCredentials
{
    $h = trim($header);
    $prefix = 'basic ';
    // Case-insensitive prefix check, mirroring Go's strings.EqualFold(h[:6], "basic ").
    if (strlen($h) < strlen($prefix) || strncasecmp($h, $prefix, strlen($prefix)) !== 0) {
        return null;
    }

    $token = trim(substr($h, strlen($prefix)));
    // strict=true -> returns false on any byte outside the base64 alphabet.
    $decoded = base64_decode($token, true);
    if ($decoded === false) {
        return null;
    }

    // Split on the FIRST colon only so a password containing colons survives.
    $idx = strpos($decoded, ':');
    if ($idx === false) {
        return null;
    }
    return new BasicAuthCredentials(
        user: substr($decoded, 0, $idx),
        pass: substr($decoded, $idx + 1),
    );
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →