https://github.com/spinen/laravel-discourse-sso
Integrate Discourse SSO into Laravel
https://github.com/spinen/laravel-discourse-sso
discourse discourse-php discourse-sso laravel laravel-5-package laravel-discourse-sso single-sign-on spinen
Last synced: 6 months ago
JSON representation
Integrate Discourse SSO into Laravel
- Host: GitHub
- URL: https://github.com/spinen/laravel-discourse-sso
- Owner: spinen
- Created: 2017-07-08T22:07:59.000Z (almost 9 years ago)
- Default Branch: develop
- Last Pushed: 2024-04-14T21:40:28.000Z (about 2 years ago)
- Last Synced: 2025-09-17T02:53:47.979Z (9 months ago)
- Topics: discourse, discourse-php, discourse-sso, laravel, laravel-5-package, laravel-discourse-sso, single-sign-on, spinen
- Language: PHP
- Homepage: https://spinen.com
- Size: 110 KB
- Stars: 49
- Watchers: 9
- Forks: 14
- Open Issues: 2
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# SPINEN's Discourse SSO for Laravel
[](https://packagist.org/packages/spinen/laravel-discourse-sso)
[](https://packagist.org/packages/spinen/laravel-discourse-sso)
[](https://packagist.org/packages/spinen/laravel-discourse-sso)
[](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
| Branch | Status | Coverage | Code Quality |
| ------ | :----: | :------: | :----------: |
| Develop | [](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=develop) | [](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=develop) | [](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=develop) |
| Master | [](https://github.com/spinen/laravel-discourse-sso/workflows/CI/badge.svg?branch=master) | [](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=master) | [](https://scrutinizer-ci.com/g/spinen/laravel-discourse-sso/?branch=master) |
## Prerequisite
#### NOTE: If you need to use < PHP 7.2, please stay with version 1.x
Aside from Laravel >= 5.5, there is 1 package that is required.
* ["cviebrock/discourse-php": "^0.9.3",](https://github.com/cviebrock/discourse-php)
## Install
Install Discourse SSO for Laravel:
```bash
$ 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
All of the configuration values are stored in under a `discourse` key in `config/services.php`. Here is the array to add...
```php
'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...
```php
/**
* Is the user a Discourse moderator?
*
* @param string $value
* @return boolean
*/
public function getDiscourseModeratorAttribute($value)
{
return ends_with($this->email, "yourdomain.tld");
}
```
## Discourse Configuration
### 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 required | true |
| enable sso | true |
| sso url | Our Laravel's SSO route (FQDN) |
| sso secret | Our SSO secret key |
| sso overrides bio | true |
| sso overrides email | true |
| sso overrides username | true |
| sso overrides name | true |
| sso overrides avatar | true |
| sso not approved url | Our Laravel homepage (same as `url` in `config/app.php`) |
| hide email address taken | true |
_______________________________________________________________________
### 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 usernames | We added our client's company name |
| min password length | 8 |
| min admin password length | 8 |
| email editable | false |
| logout redirect | Our Laravel homepage (same as `url` in `config/app.php`) |
| purge unactivated users grace period days | 30 |
| hide user profiles from public | true |
_______________________________________________________________________
## 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 & 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
```php
protected $listen = [
\Illuminate\Auth\Events\Logout::class => [
\Spinen\Discourse\Listeners\LogoutDiscourseUser::class,
],
\App\Events\YourCustomEvent::class => [
\Spinen\Discourse\Listeners\LogoutDiscourseUser::class,
],
];
```
### 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.
```php
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(
\Illuminate\Auth\Events\Logout::class,
\Spinen\Discourse\Listeners\LogoutDiscourseUser::class
);
}
```
## 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