PHPackages                             spinen/laravel-discourse-sso - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. spinen/laravel-discourse-sso

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

spinen/laravel-discourse-sso
============================

Integrate Discourse SSO into Laravel.

2.9.1(2y ago)4897.8k↓31.8%15[1 issues](https://github.com/spinen/laravel-discourse-sso/issues)[2 PRs](https://github.com/spinen/laravel-discourse-sso/pulls)MITPHPPHP &gt;=8.1

Since Jul 11Pushed 2y ago8 watchersCompare

[ Source](https://github.com/spinen/laravel-discourse-sso)[ Packagist](https://packagist.org/packages/spinen/laravel-discourse-sso)[ RSS](/packages/spinen-laravel-discourse-sso/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelog (1)Dependencies (10)Versions (30)Used By (0)

SPINEN's Discourse SSO for Laravel
==================================

[](#spinens-discourse-sso-for-laravel)

[![Latest Stable Version](https://camo.githubusercontent.com/fabc3d4efef3e60ce3bfa70fb840f64f32b440802a2494e95fb39d6c04832bd6/68747470733a2f2f706f7365722e707567782e6f72672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f762f737461626c65)](https://packagist.org/packages/spinen/laravel-discourse-sso)[![Latest Unstable Version](https://camo.githubusercontent.com/0d640e62a744fdb688e523e5c22c0c296cd541b1f330c4b66e48519ac0fb612f/68747470733a2f2f706f7365722e707567782e6f72672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f762f756e737461626c65)](https://packagist.org/packages/spinen/laravel-discourse-sso)[![Total Downloads](https://camo.githubusercontent.com/3e9d8dc1e4b33519bc4e7fec63e567dc813b88c22afac2238a32d4ae1d0f1343/68747470733a2f2f706f7365722e707567782e6f72672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f646f776e6c6f616473)](https://packagist.org/packages/spinen/laravel-discourse-sso)[![License](https://camo.githubusercontent.com/919f2fd942631404b7e2f9d6536a49af62d5b2f325f3b7fb02986df9449d0842/68747470733a2f2f706f7365722e707567782e6f72672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f6c6963656e7365)](https://packagist.org/packages/spinen/laravel-discourse-sso)

[Discourse](https://www.discourse.org) is a great online forum software that supports Single Sign On ([SSO](https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045)). There is a great PHP library that handles all of the heavy lifting to make the SSO work called [cviebrock/discourse-php](https://github.com/cviebrock/discourse-php), which this package uses. This package is loosely based on the work done by [jaewun/discourse-sso-laravel](https://github.com/jaewun/discourse-sso-laravel).

Build Status
------------

[](#build-status)

BranchStatusCoverageCode QualityDevelop[![Build Status](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=develop)](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=develop)[![Code Coverage](https://camo.githubusercontent.com/36fccabec7c7713574580b77df297f09ca2f22fdddd634aed927439b5ba17fee/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f6261646765732f636f7665726167652e706e673f623d646576656c6f70)](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=develop)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/d2345bf2a882a55c21e69647cef2d2f4d8dae41165baf5cc5d0180f8d65bd911/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f6261646765732f7175616c6974792d73636f72652e706e673f623d646576656c6f70)](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=develop)Master[![Build Status](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=master)](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=master)[![Code Coverage](https://camo.githubusercontent.com/71eaeeef5d2cf5054e84ea8e85e203c363756c333d120056d747400d27eb25d0/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/958156137dee9b5e30e9d3443a8283a93cff7e236fcea6c77e6f00b16318c487/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7370696e656e2f6c61726176656c2d646973636f757273652d73736f2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=master)Prerequisite
------------

[](#prerequisite)

#### NOTE: If you need to use &lt; PHP 7.2, please stay with version 1.x

[](#note-if-you-need-to-use--php-72-please-stay-with-version-1x)

Aside from Laravel &gt;= 5.5, there is 1 package that is required.

- ["cviebrock/discourse-php": "^0.9.3",](https://github.com/cviebrock/discourse-php)

Install
-------

[](#install)

Install Discourse SSO for Laravel:

```
$ composer require spinen/laravel-discourse-sso
```

The package uses the [auto registration feature](https://laravel.com/docs/5.8/packages#package-discovery) of Laravel 5.

Package Configuration
---------------------

[](#package-configuration)

All of the configuration values are stored in under a `discourse` key in `config/services.php`. Here is the array to add...

```
    'discourse' => [
        // Middleware for the SSO login route to use
        'middleware' => ['web', 'auth'],

        // The route's URI that acts as the entry point for Discourse to start the SSO process.
        // Used by Discourse to route incoming logins.
        'route' => 'discourse/sso',

        // Optional domain to link sso route when using SSubdomain Routing
        'domain' => null,

        // Secret string used to encrypt/decrypt SSO information,
        // be sure that it is 10 chars or longer
        'secret' => env('DISCOURSE_SECRET'),

        // Disable Discourse from sending welcome message
        'suppress_welcome_message' => 'true',

        // Where the Discourse forum lives
        'url' => env('DISCOURSE_URL'),

        // Api-specific items
        // For logging out of Discourse directly, generate an API key as an "All user key" and put the key & user here.
        // @see https://meta.discourse.org/t/how-to-create-an-api-key-on-the-admin-panel/87383
        'api' => [
            'key' => env('DISCOURSE_API_KEY'),
            'user' => env('DISCOURSE_API_USER'),
        ],

        // User-specific items
        // NOTE: The 'email' & 'external_id' are the only 2 required fields
        'user' => [
            // Check to see if the user has forum access & should be logged in via SSO
            'access' => null,

            // Discourse Groups to make sure that the user is part of in a comma-separated string
            // NOTE: Groups cannot have spaces in their names & must already exist in Discourse
            'add_groups' => null,

            // Boolean for making the user a Discourse admin. Leave null to ignore
            'admin' => null,

            // Full path to user's avatar image
            'avatar_url' => null,

            // The avatar is cached, so this triggers an update
            'avatar_force_update' => false,

            // Content of the user's bio
            'bio' => null,

            // Verified email address (see "require_activation" if not verified)
            'email' => 'email',

            // Unique string for the user that will never change
            'external_id' => 'id',

            // Boolean for making user a Discourse moderator. Leave null to ignore
            'moderator' => null,

            // Full name on Discourse if the user is new or
            // if SiteSetting.sso_overrides_name is set
            'name' => 'name',

            // Discourse Groups to make sure that the user is *NOT* part of in a comma-separated string.
            // NOTE: Groups cannot have spaces in their names & must already exist in Discourse
            // There is not a way to specify the exact list of groups that a user is in, so
            // you may want to send the inverse of the 'add_groups'
            'remove_groups' => null,

            // If the email has not been verified, set this to true
            'require_activation' => false,

            // username on Discourse if the user is new or
            // if SiteSetting.sso_overrides_username is set
            'username' => 'email',
        ],
    ],
```

The value of the properties for the `user` property can be one of 4 values...

1. `false` -- passed as set to Discourse
2. `true` -- passed as set to Discourse
3. `null` -- disables sending property to Discourse
4. a `string` -- name of a property on the `User` model

You can then add logic to the `User` model inside of [Accessors](https://laravel.com/docs/master/eloquent-mutators#defining-an-accessor) to provide the values for the properties configured for the user. For example, if you wanted any user with an email address that matched "yourdomain.tld" to be a moderator, then you could set the `moderator` property to a string like `discourse_moderator` and add the following to your `User` model...

```
    /**
     * Is the user a Discourse moderator?
     *
     * @param  string  $value
     * @return boolean
     */
    public function getDiscourseModeratorAttribute($value)
    {
        return ends_with($this->email, "yourdomain.tld");
    }
```

Discourse Configuration
-----------------------

[](#discourse-configuration)

### Settings -&gt; Login

[](#settings---login)

These are the configs we have under `Settings -> Login`. If a setting isn't listed, then ours is set to the default value.

**Setting****Value**login requiredtrueenable ssotruesso urlOur Laravel's SSO route (FQDN)sso secretOur SSO secret keysso overrides biotruesso overrides emailtruesso overrides usernametruesso overrides nametruesso overrides avatartruesso not approved urlOur Laravel homepage (same as `url` in `config/app.php`)hide email address takentrue---

### Settings -&gt; Users

[](#settings---users)

These are the configs we have under `Settings -> Users`. If a setting isn't listed, then ours is set to the default value.

**Setting****Value**reserved usernamesWe added our client's company namemin password length8min admin password length8email editablefalselogout redirectOur Laravel homepage (same as `url` in `config/app.php`)purge unactivated users grace period days30hide user profiles from publictrue---

Logging out the Discourse User
------------------------------

[](#logging-out-the-discourse-user)

There's a listener in `src/Listeners/LogoutDiscourseUser.php` that will automatically log out the user from Discourse when certain events are fired. To use the Listener, [you need to register the event](https://laravel.com/docs/master/events#registering-events-and-listeners) in the `$listen` array in your `EventServiceProvider`.

When a Laravel `User` logs out, to log out their Discourse session Simply add the Laravel `Logout` event &amp; the `LogoutDiscourseUser` listener in that `$listen` array. If you want to log out Discourse users on a Laravel `User` being deleted or disabled, make your own event class and register it the same way.

### Example

[](#example)

```
    protected $listen = [
        \Illuminate\Auth\Events\Logout::class => [
            \Spinen\Discourse\Listeners\LogoutDiscourseUser::class,
        ],
        \App\Events\YourCustomEvent::class => [
            \Spinen\Discourse\Listeners\LogoutDiscourseUser::class,
        ],
    ];
```

### Laravel 11

[](#laravel-11)

In Laravel 11, the use of the `EventServiceProvider` is discouraged and events [should be registered in the `AppServiceProvider`](https://laravel.com/docs/11.x/events#manually-registering-events).

Therefore, the implementation is slightly different, and it should be registered within the `boot` method of the `AppServiceProvider` as per the example below.

```
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Event::listen(
            \Illuminate\Auth\Events\Logout::class,
            \Spinen\Discourse\Listeners\LogoutDiscourseUser::class
        );
    }
```

Left to do
----------

[](#left-to-do)

- badges for user
- support for [`custom_fields`](https://meta.discourse.org/t/custom-user-fields-for-plugins/14956)
- failed login redirect
- `return_paths` support

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity43

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity83

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 57.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~112 days

Recently: every ~196 days

Total

23

Last Release

764d ago

Major Versions

1.5.0 → 2.0.02019-02-26

PHP version history (3 changes)1.0.0PHP &gt;=5.5.9

2.0.0PHP &gt;=7.2

2.8.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/a082f934783fa6f391c37fc7e7ca71f84e17219471cadd17a8b8b85b42c2c9c1?d=identicon)[david.mathews](/maintainers/david.mathews)

![](https://www.gravatar.com/avatar/782b3ad6f100c625875d6a8f00222d0e08e0c6f0956ef757e43a38441594c013?d=identicon)[jimmypuckett](/maintainers/jimmypuckett)

![](https://www.gravatar.com/avatar/a03d6c15997b49e0fa73b6e61f6c4fbc833f1f0d2476984fe88bb38a8b866c2d?d=identicon)[ssfinney](/maintainers/ssfinney)

---

Top Contributors

[![jimmypuckett](https://avatars.githubusercontent.com/u/3220069?v=4)](https://github.com/jimmypuckett "jimmypuckett (127 commits)")[![ssfinney](https://avatars.githubusercontent.com/u/1596394?v=4)](https://github.com/ssfinney "ssfinney (87 commits)")[![shugyosha89](https://avatars.githubusercontent.com/u/59955181?v=4)](https://github.com/shugyosha89 "shugyosha89 (2 commits)")[![trippo](https://avatars.githubusercontent.com/u/497169?v=4)](https://github.com/trippo "trippo (2 commits)")[![lucasdcrk](https://avatars.githubusercontent.com/u/17224437?v=4)](https://github.com/lucasdcrk "lucasdcrk (1 commits)")[![jtolj](https://avatars.githubusercontent.com/u/845525?v=4)](https://github.com/jtolj "jtolj (1 commits)")[![JamieBradders](https://avatars.githubusercontent.com/u/9695673?v=4)](https://github.com/JamieBradders "JamieBradders (1 commits)")

---

Tags

discoursediscourse-phpdiscourse-ssolaravellaravel-5-packagelaravel-discourse-ssosingle-sign-onspinenlaravellibrarySSOsingle sign ondiscoursespinen

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/spinen-laravel-discourse-sso/health.svg)

```
[![Health](https://phpackages.com/badges/spinen-laravel-discourse-sso/health.svg)](https://phpackages.com/packages/spinen-laravel-discourse-sso)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[codegreencreative/laravel-samlidp

Make your PHP Laravel application an Identification Provider using SAML 2.0. This package allows you to implement your own Identification Provider (idP) using the SAML 2.0 standard to be used with supporting SAML 2.0 Service Providers (SP).

263763.5k1](/packages/codegreencreative-laravel-samlidp)[truckersmp/steam-socialite

Laravel Socialite provider for Steam OpenID.

1516.7k](/packages/truckersmp-steam-socialite)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
