Add bot support
This commit is contained in:
parent
5c10e0f1e8
commit
7a28af23dd
64
README.md
64
README.md
|
|
@ -1,10 +1,9 @@
|
||||||
# Discord provider for Laravel Socialite
|
# Discord provider for Laravel Socialite
|
||||||
A provider for [Laravel Socialite][1] that allows authentication as a Discord user.
|
A provider for [Laravel Socialite][1] that allows authentication as a Discord user or bot.
|
||||||
_Authenticating as a bot is currently not supported._
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```
|
```
|
||||||
composer require martinbean/socialite-discord-provider
|
composer require martinbean/socialite-discord-provider:^1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
@ -13,8 +12,7 @@ The package registers a Socialite driver with the name of `discord`.
|
||||||
Before using the driver, create an OAuth application in Discord’s developer portal:
|
Before using the driver, create an OAuth application in Discord’s developer portal:
|
||||||
https://discord.com/developers/applications
|
https://discord.com/developers/applications
|
||||||
|
|
||||||
Set your client ID and client secret as environment variables, and then reference them in your **config/services.php** file.
|
Set your client ID and client secret as environment variables, and then reference them in your **config/services.php** file. You will also need to add a redirect URL to your application if you intend to authenticate as a user.
|
||||||
You will also need to add a redirect URL to your application.
|
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
@ -36,7 +34,8 @@ return [
|
||||||
|
|
||||||
The `redirect` value will need to match a redirect URL in your Discord application settings. It can be relative as above.
|
The `redirect` value will need to match a redirect URL in your Discord application settings. It can be relative as above.
|
||||||
|
|
||||||
Then, create a controller to redirect and handle the token callback:
|
### Authenticating as a user
|
||||||
|
Create a controller to redirect and handle the access token callback:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
@ -72,8 +71,9 @@ class DiscordController extends Controller
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Scopes
|
#### Scopes
|
||||||
Discord supports various scopes. You can find a list here: https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes
|
Discord supports various scopes when authenticating as a user. You can find a list here: https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes
|
||||||
|
|
||||||
To request additional scopes when authenticating, you can use the `scopes` method before redirecting:
|
To request additional scopes when authenticating, you can use the `scopes` method before redirecting:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
|
@ -82,6 +82,54 @@ return Socialite::driver('discord')
|
||||||
->redirect();
|
->redirect();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Authenticating as a bot
|
||||||
|
Discord allows you to add “bots” to guilds (servers). This is a modified OAuth flow, where you are redirected to Discord to confirm the guild you wish to add a bot to. There is no redirect back to your application when you authorize the request.
|
||||||
|
|
||||||
|
You can authenticate as a bot by using the `bot` method before redirecting:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Laravel\Socialite\Facades\Socialite;
|
||||||
|
|
||||||
|
class DiscordController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Redirect the user to the Discord authentication page.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function redirectToProvider()
|
||||||
|
{
|
||||||
|
return Socialite::driver('discord')->bot()->redirect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you know the guild ID you wish to add your bot to, you may specify it with the `guild` method:
|
||||||
|
|
||||||
|
```php
|
||||||
|
return Socialite::driver('discord')
|
||||||
|
->bot()
|
||||||
|
->guild($guildId)
|
||||||
|
->redirect();
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, you can disable the guild select:
|
||||||
|
|
||||||
|
```php
|
||||||
|
return Socialite::driver('discord')
|
||||||
|
->bot()
|
||||||
|
->guild($guildId)
|
||||||
|
->disableGuildSelect()
|
||||||
|
->redirect();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** if you try and disable guild selection without specifying a guild, the package will throw a `GuildRequiredException` instance.
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
If you have any problems using this package, please open an issue on the [GitHub repository][2].
|
If you have any problems using this package, please open an issue on the [GitHub repository][2].
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "martinbean/socialite-discord-provider",
|
"name": "martinbean/socialite-discord-provider",
|
||||||
"description": "A Discord provider for Laravel Socialite.",
|
"description": "A Discord provider for Laravel Socialite.",
|
||||||
"version": "1.0",
|
"version": "1.1.0",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"laravel",
|
"laravel",
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
"source": "https://github.com/martinbean/socialite-discord-provider"
|
"source": "https://github.com/martinbean/socialite-discord-provider"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"facade/ignition-contracts": "^1.0",
|
||||||
"laravel/socialite": "^4.0"
|
"laravel/socialite": "^4.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MartinBean\Laravel\Socialite;
|
||||||
|
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use MartinBean\Laravel\Socialite\Exceptions\GuildRequiredException;
|
||||||
|
|
||||||
|
class BotRedirectBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The client ID.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $clientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The permissions to request.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $permissions = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The guild to pre-fill the dropdown picker with.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $guild;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to disallow the user from changing the guild dropdown.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $disableGuildSelect = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new bot redirect builder instance.
|
||||||
|
*
|
||||||
|
* @param string $clientId
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(string $clientId)
|
||||||
|
{
|
||||||
|
$this->clientId = $clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the permissions to request.
|
||||||
|
*
|
||||||
|
* @param int $permissions
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function permissions(int $permissions)
|
||||||
|
{
|
||||||
|
$this->permissions = $permissions;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-fill the dropdown picker with a guild for the user.
|
||||||
|
*
|
||||||
|
* @param string|int $guild
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function guild($guild)
|
||||||
|
{
|
||||||
|
$this->guild = (string) $guild;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disallow the user from changing the guild dropdown.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function disableGuildSelect()
|
||||||
|
{
|
||||||
|
$this->disableGuildSelect = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect the user of the application to the provider's authentication screen.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function redirect()
|
||||||
|
{
|
||||||
|
return new RedirectResponse($this->getAuthUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authentication URL for the provider.
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function buildAuthUrlFromBase($url)
|
||||||
|
{
|
||||||
|
return $url.'?'.http_build_query($this->getCodeFields(), '', '&', PHP_QUERY_RFC1738);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GET parameters for the code request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \MartinBean\Laravel\Socialite\Exceptions\GuildRequiredException
|
||||||
|
*/
|
||||||
|
protected function getCodeFields()
|
||||||
|
{
|
||||||
|
if ($this->disableGuildSelect && ! $this->guild) {
|
||||||
|
throw new GuildRequiredException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'client_id' => $this->clientId,
|
||||||
|
'scope' => 'bot',
|
||||||
|
'permissions' => $this->permissions,
|
||||||
|
'guild_id' => $this->guild,
|
||||||
|
'disable_guild_select' => $this->disableGuildSelect ? 'true' : 'false',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authentication URL for the provider.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getAuthUrl()
|
||||||
|
{
|
||||||
|
return $this->buildAuthUrlFromBase('https://discord.com/api/oauth2/authorize');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,16 @@ class DiscordProvider extends AbstractProvider implements ProviderInterface
|
||||||
*/
|
*/
|
||||||
protected $scopeSeparator = ' ';
|
protected $scopeSeparator = ' ';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new bot redirect.
|
||||||
|
*
|
||||||
|
* @return \MartinBean\Laravel\Socialite\BotRedirectBuilder
|
||||||
|
*/
|
||||||
|
public function bot()
|
||||||
|
{
|
||||||
|
return new BotRedirectBuilder($this->clientId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ class DiscordServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
return new DiscordProvider(
|
return new DiscordProvider(
|
||||||
$app->make('request'),
|
$app->make('request'),
|
||||||
Arr::get($config, 'client_id', ''),
|
$config['client_id'],
|
||||||
Arr::get($config, 'client_secret', ''),
|
$config['client_secret'],
|
||||||
Str::startsWith($redirect, '/') ? $app->make('url')->to($redirect) : $redirect,
|
Str::startsWith($redirect, '/') ? $app->make('url')->to($redirect) : $redirect,
|
||||||
Arr::get($config, 'guzzle', [])
|
Arr::get($config, 'guzzle', [])
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MartinBean\Laravel\Socialite\Exceptions;
|
||||||
|
|
||||||
|
use Facade\IgnitionContracts\BaseSolution;
|
||||||
|
use Facade\IgnitionContracts\ProvidesSolution;
|
||||||
|
use Facade\IgnitionContracts\Solution;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class GuildRequiredException extends RuntimeException implements ProvidesSolution
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The exception message.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $message = 'A guild is required if you are going to disable the guild select';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the exception solution.
|
||||||
|
*
|
||||||
|
* @return \Facade\IgnitionContracts\Solution
|
||||||
|
*/
|
||||||
|
public function getSolution(): Solution
|
||||||
|
{
|
||||||
|
return BaseSolution::create('Specify a guild ID before redirecting')
|
||||||
|
->setSolutionDescription('Call `guild($guildId)` before redirecting.');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue