荷兰编码公司/filament-socialite

通过 Laravel Socialite 为 Filament 实现社交登录

2.2.1 2024-07-17 08:25 UTC

README

通过 Laravel Socialite 为 Filament 实现社交登录

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

通过 Laravel Socialite 将 OAuth2 登录添加到 Filament。目前不支持 OAuth1(例如 Twitter)。

安装

通过 composer 安装此包

composer require dutchcodingcompany/filament-socialite

发布并迁移迁移文件

php artisan vendor:publish --tag="filament-socialite-migrations"
php artisan migrate

其他配置文件包括

php artisan vendor:publish --tag="filament-socialite-config"
php artisan vendor:publish --tag="filament-socialite-views"
php artisan vendor:publish --tag="filament-socialite-translations"

您需要在 Filament 面板提供者中注册插件(默认文件名为 app/Providers/Filament/AdminPanelProvider.php)。以下选项可用

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use DutchCodingCompany\FilamentSocialite\Provider;
use Filament\Support\Colors;
use Laravel\Socialite\Contracts\User as SocialiteUserContract;
use Illuminate\Contracts\Auth\Authenticatable;

// ...
->plugin(
    FilamentSocialitePlugin::make()
        // (required) Add providers corresponding with providers in `config/services.php`. 
        ->providers([
            // Create a provider 'gitlab' corresponding to the Socialite driver with the same name.
            Provider::make('gitlab')
                ->label('GitLab')
                ->icon('fab-gitlab')
                ->color(Color::hex('#2f2a6b'))
                ->outlined(false)
                ->stateless(false)
                ->scopes(['...'])
                ->with(['...']),
        ])
        // (optional) Override the panel slug to be used in the oauth routes. Defaults to the panel ID.
        ->slug('admin')
        // (optional) Enable/disable registration of new (socialite-) users.
        ->registration(true)
        // (optional) Enable/disable registration of new (socialite-) users using a callback.
        // In this example, a login flow can only continue if there exists a user (Authenticatable) already.
        ->registration(fn (string $provider, SocialiteUserContract $oauthUser, ?Authenticatable $user) => (bool) $user)
        // (optional) Change the associated model class.
        ->userModelClass(\App\Models\User::class)
        // (optional) Change the associated socialite class (see below).
        ->socialiteUserModelClass(\App\Models\SocialiteUser::class)
);

此包自动为每个面板添加 2 个路由以实现 OAuth 流:重定向器和回调。当设置您的 外部 OAuth 应用配置 时,请输入以下回调 URL(在这种情况下,对于 ID 为 admin 且提供者为 github 的 Filament 面板)

https://example.com/admin/oauth/callback/github

还有一个多面板回调路由,该路由不包含 URL 中的面板 ID。相反,它从加密的 state 输入(例如 ...?state=abcd1234)中确定面板 ID。这允许您为使用相同回调 URL 的多个 Filament 面板创建单个 OAuth 应用程序。请注意,这仅适用于 有状态的 OAuth 应用程序。

https://example.com/oauth/callback/github

如有疑问,请运行 php artisan route:list 以查看您可用的路由。

CSRF 保护

(Laravel 11.x 用户可以忽略此部分)

如果您的第三方提供商使用 POST 请求调用 OAuth 回调,您需要将回调路由添加到您的 VerifyCsrfToken 中间件的异常列表中。这可以通过将 URL 添加到 $except 数组来实现

protected $except = [
    '*/oauth/callback/*',
    'oauth/callback/*',
];

Laravel 11.x 用户,此异常由我们的服务提供商自动添加。

有关更多信息,请参阅 Socialite Providers

图标

您可以为每个登录提供者指定自定义图标。您可以通过运行以下命令添加由 Blade Font Awesome 提供的 Font Awesome 品牌图标:

composer require owenvoke/blade-fontawesome

注册流程

此包支持为用户创建账户。但是,为了支持此流程,您在 User 模型上的 password 属性必须为可空。例如,您可以通过向您的用户表迁移中添加以下内容来实现。或者,您可以选择自定义用户创建,见下文。

$table->string('password')->nullable();

域名允许列表

此包支持限制可以使用 OAuth 登录登录的用户为特定域的用户的功能。这可以用于设置内部使用的 SSO。

->plugin(
    FilamentSocialitePlugin::make()
        // ...
        ->registration(true)
        ->domainAllowList(['localhost'])
);

更改 Authenticatable 用户创建或检索的方式

您可以使用 createUserUsingresolveUserUsing 方法来更改创建或检索用户的方式。

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use Laravel\Socialite\Contracts\User as SocialiteUserContract;

->plugin(
    FilamentSocialitePlugin::make()
        // ...
        ->createUserUsing(function (string $provider, SocialiteUserContract $oauthUser, FilamentSocialitePlugin $plugin) {
            // Logic to create a new user.
        })
        ->resolveUserUsing(function (string $provider, SocialiteUserContract $oauthUser, FilamentSocialitePlugin $plugin) {
            // Logic to retrieve an existing user.
        })
        ...
);

更改 Socialite 用户创建或检索的方式

在您的 Filament 面板插件选项中添加以下方法

// app/Providers/Filament/AdminPanelProvider.php
->plugins([
    FilamentSocialitePlugin::make()
        // ...
        ->socialiteUserModelClass(\App\Models\SocialiteUser::class)

此类至少应实现 FilamentSocialiteUser 接口,如下所示

namespace App\Models;

use DutchCodingCompany\FilamentSocialite\Models\Contracts\FilamentSocialiteUser as FilamentSocialiteUserContract;
use Illuminate\Contracts\Auth\Authenticatable;
use Laravel\Socialite\Contracts\User as SocialiteUserContract;

class SocialiteUser implements FilamentSocialiteUserContract
{
    public function getUser(): Authenticatable
    {
        //
    }

    public static function findForProvider(string $provider, SocialiteUserContract $oauthUser): ?self
    {
        //
    }
    
    public static function createForProvider(
        string $provider,
        SocialiteUserContract $oauthUser,
        Authenticatable $user
    ): self {
        //
    }
}

检查用户是否有权使用应用程序

您可以使用authorizeUserUsing方法来检查用户是否有权使用应用程序。 注意:默认情况下,此方法检查用户的电子邮件域名是否在域名允许列表中。

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use Laravel\Socialite\Contracts\User as SocialiteUserContract;

->plugin(
    FilamentSocialitePlugin::make()
        // ...
        ->authorizeUserUsing(function (FilamentSocialitePlugin $plugin, SocialiteUserContract $oauthUser) {
            // Logic to authorize the user.
            return FilamentSocialitePlugin::checkDomainAllowList($plugin, $oauthUser);
        })
        // ...
);

更改登录重定向

当您的面板启用多租户功能后,登录后用户将被重定向到他们的默认租户。如果您想更改此行为,可以在FilamentSocialitePlugin上调用'redirectAfterLoginUsing'方法。

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use DutchCodingCompany\FilamentSocialite\Models\Contracts\FilamentSocialiteUser as FilamentSocialiteUserContract;
use DutchCodingCompany\FilamentSocialite\Models\SocialiteUser;

FilamentSocialitePlugin::make()
    ->redirectAfterLoginUsing(function (string $provider, FilamentSocialiteUserContract $socialiteUser, FilamentSocialitePlugin $plugin) {
        // Change the redirect behaviour here.
    });

Filament Fortify

在使用Fortify插件插件时,也可以添加此组件。

## in Service Provider file
public function boot()
{
    //...
    
    Filament::registerRenderHook(
        'filament-fortify.login.end',
        fn (): string => Blade::render('<x-filament-socialite::buttons />'),
    );
}

Filament Breezy

Breezy插件插件中使用时,也可以添加此组件。

您可以通过以下命令发布的登录页面:

php artisan vendor:publish --tag="filament-breezy-views"

这将产生一个位于resources/views/vendor/filament-breezy/login.blade.php的登录页面。

然后您可以在表单中添加以下代码片段

<x-filament-socialite::buttons />

事件

在身份验证过程中会触发一些事件

  • InvalidState(InvalidStateException $exception):尝试检索oauth(socialite)用户时遇到无效状态
  • Login(FilamentSocialiteUserContract $socialiteUser):用户成功登录时
  • Registered(FilamentSocialiteUserContract $socialiteUser):用户和socialite用户成功注册并登录(当启用配置时)
  • RegistrationNotEnabled(string $provider, SocialiteUserContract $oauthUser):当用户尝试使用未知账户登录且未启用注册时
  • SocialiteUserConnected(FilamentSocialiteUserContract $socialiteUser):为现有用户创建socialite用户时
  • UserNotAllowed(SocialiteUserContract $oauthUser):当用户尝试使用不在允许列表中的电子邮件登录时

作用域

您可以在面板上向提供者添加作用域,例如

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use DutchCodingCompany\FilamentSocialite\Provider;

FilamentSocialitePlugin::make()
    ->providers([
        Provider::make('github')
            ->label('Github')
            ->icon('fab-github')
            ->scopes([
                // Add scopes here.
                'read:user',
                'public_repo',
            ]),
    ]),

可选参数

您可以通过在面板上的提供者中添加with键向请求添加可选参数,例如

use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use DutchCodingCompany\FilamentSocialite\Provider;

FilamentSocialitePlugin::make()
    ->providers([
        Provider::make('github')
            ->label('Github')
            ->icon('fab-github')
            ->with([
                // Add scopes here.
                // Add optional parameters here.
                'hd' => 'example.com',
            ]),
    ]),

无状态认证

您可以在config/services.php配置文件中的提供者配置中添加stateless参数,例如

'apple' => [
    'client_id' => '...',
    'client_secret' => '...',
    'stateless'=>true,
]

注意:您不能使用state参数,因为它用于确定用户来自哪个Filament面板。

变更日志

请参阅变更日志以获取有关最近更改的更多信息。

贡献

请参阅贡献指南以获取详细信息。

安全漏洞

请审查我们的安全策略,了解如何报告安全漏洞。

鸣谢

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。