xervo / kord
Authentication for Laravel with Discord
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/xervo/kord
Requires
- php: ^8.1
- laravel/framework: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- pestphp/pest: ^2.0|^3.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0
README
Kord is a Laravel package that provides seamless Discord OAuth2 authentication for your Laravel applications. It handles user authentication, token management, and provides easy access to Discord user data.
Features
- 🔐 Discord OAuth2 Authentication - Complete OAuth2 flow implementation
- 👤 User Management - Automatic user creation and updates
- 🔄 Token Management - Automatic token refresh and expiration handling
- 📦 Extended Data Storage - Optional storage of full Discord user data
- 🎨 Helper Methods - Easy access to Discord information (Nitro, colors, avatars, etc.)
- 🔧 Trait Support - Use the
HasDiscordtrait for direct User model access - 🛠️ Installation Command - Interactive setup with
kord:install - 📝 Well Documented - Comprehensive documentation and examples
Requirements
- PHP 8.1 or higher
- Laravel 10.0 or higher
- Discord Application (Client ID and Secret)
Installation
Step 1: Install via Composer
composer require xervo/kord
Step 2: Run the Installation Command
php artisan kord:install
This interactive command will:
- Prompt for your Discord Client ID
- Prompt for your Discord Client Secret
- Set up your redirect URI
- Optionally enable extended data storage
- Update your
.envfile automatically
Step 3: Publish Migrations
php artisan vendor:publish --tag=kord-migrations php artisan migrate
Step 4: Publish Config (Optional)
php artisan vendor:publish --tag=kord-config
Discord Application Setup
- Go to Discord Developer Portal
- Create a new application or select an existing one
- Navigate to the "OAuth2" section
- Add your redirect URI (e.g.,
http://localhost/auth/discord/callback) - Copy your Client ID and Client Secret
- Use these values during the
kord:installcommand
Configuration
Environment Variables
After running kord:install, your .env file will contain:
DISCORD_CLIENT_ID=your_client_id_here DISCORD_CLIENT_SECRET=your_client_secret_here DISCORD_REDIRECT_URI=/auth/discord/callback DISCORD_STORE_EXTENDED_DATA=false
Config File
If you published the config file, you can customize additional settings in config/kord.php:
return [ 'client_id' => env('DISCORD_CLIENT_ID', ''), 'client_secret' => env('DISCORD_CLIENT_SECRET', ''), 'redirect_uri' => env('DISCORD_REDIRECT_URI', '/auth/discord/callback'), 'scopes' => env('DISCORD_SCOPES', 'identify email'), 'store_extended_data' => env('DISCORD_STORE_EXTENDED_DATA', false), // ... more options ];
Usage
Basic Authentication Flow
1. Redirect Users to Discord
use Xervo\Kord\Facades\Kord; // In your controller or route return redirect(Kord::getAuthorizationUrl());
Or use the provided route:
// In your blade template <a href="{{ route('discord.login') }}">Login with Discord</a>
2. Handle Callback
The package automatically handles the OAuth callback at /auth/discord/callback. Users will be:
- Created if they don't exist
- Updated with latest Discord information
- Logged in automatically
3. Access Discord Data
use Xervo\Kord\Facades\Kord; // Get current user's Discord info $discordInfo = Kord::getCurrentUserDiscordInfo(); // Get avatar URL $avatarUrl = Kord::getCurrentUserAvatarUrl(256); // Get full username $username = Kord::getCurrentUserFullUsername(); // Get specific field $nitroStatus = Kord::getCurrentUserDiscordField('premium_type');
Using the HasDiscord Trait
Add the trait to your User model:
use Xervo\Kord\Traits\HasDiscord; class User extends Authenticatable { use HasFactory, Notifiable, HasDiscord; // ... your model code }
Now you can access Discord data directly on the User model:
$user = User::find(1); // Check if user has Discord if ($user->hasDiscord()) { // Get Discord information $username = $user->getDiscordFullUsername(); $avatarUrl = $user->getDiscordAvatarUrl(256); $bannerUrl = $user->getDiscordBannerUrl(1024); $accentColor = $user->getDiscordAccentColorHex(); // Check account status $hasNitro = $user->hasDiscordNitro(); $isVerified = $user->isDiscordVerified(); $hasMfa = $user->hasDiscordMfa(); // Access relationships $token = $user->discordToken; $extendedData = $user->discordData; // Refresh data from Discord $user->refreshDiscordData(); }
Extended Data Storage
When enabled, the package stores the complete Discord API response in a separate table. This allows access to all Discord fields without cluttering your users table.
Enable Extended Data Storage
Set in your .env:
DISCORD_STORE_EXTENDED_DATA=true
Or during installation, answer "yes" when prompted.
Access Extended Data
use Xervo\Kord\Facades\Kord; $extendedData = Kord::getCurrentUserExtendedData(); if ($extendedData) { // Use helper methods $hasNitro = $extendedData->hasNitro(); $accentColor = $extendedData->getAccentColorHex(); $bannerUrl = $extendedData->getBannerUrl(); // Get any field $customField = $extendedData->getField('some_field', 'default'); // Get all data $allData = $extendedData->getAllData(); }
Available Routes
The package provides the following routes:
| Route | Method | Description |
|---|---|---|
/auth/discord |
GET | Redirect to Discord OAuth |
/auth/discord/callback |
GET | OAuth callback handler |
/auth/discord/logout |
POST | Logout and revoke tokens |
/auth/discord/refresh |
POST | Refresh Discord data |
Helper Methods
Kord Facade Methods
use Xervo\Kord\Facades\Kord; // OAuth Kord::getAuthorizationUrl($state = null); Kord::exchangeCodeForToken($code); Kord::getUser($accessToken); Kord::refreshToken($refreshToken); Kord::revokeToken($token); // Current User Kord::getCurrentUserToken(); Kord::getCurrentUserDiscordInfo(); Kord::getCurrentUserExtendedData(); Kord::getCurrentUserDiscordField($field, $default); Kord::getCurrentUserAvatarUrl($size); Kord::getCurrentUserFullUsername(); Kord::refreshCurrentUserData();
HasDiscord Trait Methods
// Relationships $user->discordToken(); $user->discordData(); // Status $user->hasDiscord(); $user->isDiscordVerified(); $user->hasDiscordMfa(); $user->hasDiscordNitro(); $user->isDiscordBot(); $user->isDiscordSystem(); // Data Access $user->getDiscordId(); $user->getDiscordUsername(); $user->getDiscordFullUsername(); $user->getDiscordAvatarUrl($size); $user->getDiscordBannerUrl($size); $user->getDiscordAccentColorHex(); $user->getDiscordEmail(); $user->getDiscordLocale(); $user->getDiscordPremiumType(); $user->getDiscordPublicFlags(); $user->getDiscordField($field, $default); $user->getAllDiscordData(); $user->hasDiscordField($key); $user->refreshDiscordData();
Database Structure
Users Table
The package adds the following columns to your users table:
discord_id- Unique Discord user IDdiscord_username- Discord usernamediscord_discriminator- Discord discriminatordiscord_avatar- Avatar hashdiscord_verified- Verification status
discord_access_tokens Table
Stores OAuth tokens:
user_id- Foreign key to usersaccess_token- Discord access tokenrefresh_token- Refresh tokenexpires_at- Token expirationtoken_type- Token type (usually "Bearer")scope- OAuth scopes
discord_user_data Table (Optional)
Stores extended Discord data when enabled:
user_id- Foreign key to usersdata- JSON field with complete Discord user data
Examples
Example 1: Display User Avatar
@auth @php $avatarUrl = \Xervo\Kord\Facades\Kord::getCurrentUserAvatarUrl(128); @endphp @if($avatarUrl) <img src="{{ $avatarUrl }}" alt="Avatar" class="rounded-full"> @endif @endauth
Example 2: Check for Nitro
use Xervo\Kord\Facades\Kord; $extendedData = Kord::getCurrentUserExtendedData(); if ($extendedData && $extendedData->hasNitro()) { echo "User has Discord Nitro!"; echo "Premium Type: " . $extendedData->getPremiumType(); }
Example 3: Use Accent Color
@php $user = auth()->user(); $accentColor = $user->getDiscordAccentColorHex(); @endphp @if($accentColor) <div style="background-color: {{ $accentColor }};"> User's Discord accent color </div> @endif
Example 4: Refresh User Data
use Xervo\Kord\Facades\Kord; // Refresh current authenticated user $success = Kord::refreshCurrentUserData(); // Or using the trait $user = User::find(1); $success = $user->refreshDiscordData();
Example 5: List All Discord Users
use App\Models\User; $discordUsers = User::whereNotNull('discord_id')->get(); foreach ($discordUsers as $user) { echo $user->getDiscordFullUsername(); echo $user->getDiscordAvatarUrl(64); }
Troubleshooting
"Session store not set on request"
Make sure your routes are using the web middleware group. The package routes are automatically wrapped in this middleware.
Discord data not saving
Ensure the Discord fields are accessible. The package uses forceFill() to bypass mass assignment, but you may want to add them to your User model's $fillable array:
protected $fillable = [ 'name', 'email', 'password', 'discord_id', 'discord_username', 'discord_discriminator', 'discord_avatar', 'discord_verified', ];
Token expired errors
The package automatically refreshes tokens when they expire. If you're seeing errors, ensure:
- Refresh tokens are being stored
- Your Discord application has the correct scopes
- The token hasn't been revoked
Extended data not showing
- Check that
DISCORD_STORE_EXTENDED_DATA=truein your.env - Run migrations:
php artisan migrate - Re-authenticate with Discord to populate the data
Security Considerations
- Never commit your
.envfile with Discord credentials - Use HTTPS in production for OAuth callbacks
- Validate state parameter (handled automatically by the package)
- Store tokens securely (the package handles this in the database)
- Revoke tokens on logout (handled automatically)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This package is open-sourced software licensed under the MIT license.
Support
For issues, questions, or contributions, please visit the GitHub repository.
Credits
- Created by Debug
- Built for the Laravel community
Made with ❤️ for Laravel developers