cviebrock/discourse-php
A PHP client for the Discourse forum API that helps PHP and Laravel applications manage users, groups, topics, and notifications. It simplifies integrating community features, syncing accounts, and automating common Discourse tasks.
Architecture fit. cviebrock/discourse-php is a thin, framework-agnostic helper (~one class) that implements the Discourse Connect (SSO) provider side of the protocol: parse the incoming sso/sig query parameters, validate the HMAC-SHA256 signature, expose the nonce, and build the signed redirect payload containing user attributes. It is not a Laravel package in the conventional sense — it ships no service provider, facade, config file, or migrations. In a Laravel codebase it fits cleanly as an adapter: bind the helper as a singleton in a small service provider with the shared secret injected from config/services.php, and expose a single controller endpoint (e.g. GET /discourse/sso) that validates the payload, authorizes and maps the local user, and redirects back to the forum. That is a minimal, well-bounded surface area — the ideal shape for a third-party dependency.
Integration feasibility. High. MIT license, Composer-installable, no transitive dependencies beyond PHP itself, and the Discourse SSO protocol is stable and publicly documented. The real integration work is not the helper but the surrounding decisions: choosing an immutable external_id (Laravel's user primary key, never the email), mapping username/name/avatar_url, deciding on JIT provisioning vs. pre-provisioning, and handling admin/moderator and group membership.
Technical risk. Low code risk, elevated lifecycle risk. The package is effectively unmaintained — no recent releases, 66 stars, and 0 Packagist dependents, which means almost no production validation to draw on and no community to absorb a security fix. The class predates modern PHP typing and composer.json likely declares a permissive floor like php >=5.4, so it will install on PHP 8.x but is unlikely to have been tested there. Notably, the helper validates the signature but does not provide nonce replay protection or validate that the caller-supplied return_sso_url matches the configured forum; both are security-critical and must be implemented by us. Since the class is small, forking or vendoring it is cheap and neutralizes the abandonment risk.
Key questions.
hash_equals, null handling)?Stack fit. Laravel 9–11, PHP 8.x. The seam is a single route, a small DiscourseSsoService wrapper around the helper, and a config entry for secret and forum base URL. All identity logic stays in our domain — the package never touches the database, session, or HTTP layer.
Migration path. If replacing an existing forum bridge (custom SSO, phpBB, or Discourse's built-in OAuth), sequence the cutover so accounts map by immutable identifier rather than email. Backfill external_id from the Laravel user ID, dry-run against a staging Discourse instance, then flip the forum's SSO settings during a low-traffic window. If no forum exists yet, this package is cheap enough to spike in an afternoon before any commitment.
Compatibility. The wire format is stable: URL-safe base64 payload, HMAC-SHA256 signature, sso and sig parameters, return_sso_url for the callback. The compatibility questions are entirely on our side — PHP runtime, and whether we vendor the class to insulate against an abandoned upstream. Because it's a single file, vendoring or a one-file fork with hash_equals and typed signatures is a low-cost hardening step.
Sequencing.
return_sso_url allowlisting against the configured forum host.Maintenance. Ongoing maintenance is near zero in code terms (~150–200 LOC) but non-zero in ownership terms: with no upstream releases and no dependents, we should assume we own this code permanently. Budget a fork/vendor, a pinned commit, and an annual review for PHP compatibility. The upside is that the logic is small enough to audit fully, which is more than can be said for most auth dependencies.
Support. No vendor. Support relies on the GitHub issue tracker, Discourse's Meta documentation, and our own runbook. Document the secret, the endpoint, the nonce store, and the failure signatures so on-call can distinguish "secret mismatch" from "user mapping bug."
Scaling. Effectively free — HMAC is stateless and O(nothing) per login, so it scales horizontally with the Laravel app. The only stateful piece is nonce replay protection, which needs a shared cache (Redis) if the app runs multi-node, plus a TTL slightly longer than the login round trip.
Failure modes.
return_sso_url → open-redirect/data-exfiltration of the signed user payload; must be allowlisted.external_id as the sole join key.Ramp-up. Very low. A mid-level Laravel engineer can complete the happy-path integration in one to two days; most of that is learning the Discourse payload semantics and deciding the user-mapping policy, not the library. The one-to-two-week figure applies only if you also build provisioning, group sync, email sync, and replay protection — which this package deliberately leaves to you.
How can I help you explore Laravel packages today?