slashid/laravel

SlashID 集成包用于 Laravel。

安装: 1

依赖项: 0

建议者: 0

安全性: 0

星级: 0

关注者: 0

分支: 0

开放性问题: 1

语言:JavaScript

1.0.0 2024-04-04 16:23 UTC

This package is not auto-updated.

Last update: 2024-09-20 13:38:24 UTC


README

安装

  1. 使用 composer 安装 Laravel 的 SlashID 包
composer require slashid/laravel
  1. 编辑您的环境文件 .env,在文件末尾添加以下变量
    • SLASHID_ENVIRONMENT,可以是 sandboxproduction
    • SLASHID_ORGANIZATION_ID,您的组织 ID。您可以在 SlashID 控制台(生产环境:https://console.slashid.dev/,沙盒环境:https://console.sandbox.slashid.dev/)的“设置”选项卡中找到,页面顶部。
    • SLASHID_API_KEY,您的组织 API 密钥。您也可以在 SlashID 控制台的“设置”选项卡中找到,页面底部。
SLASHID_ENVIRONMENT=sandbox
SLASHID_ORGANIZATION_ID=412edb57-ae26-f2aa-9999-770021ed52d1
SLASHID_API_KEY=z0dlY-nluiq8mcvm8YTolSkJV6e9
  1. 运行以下 artisan 命令以发布资源
php artisan vendor:publish --provider="SlashId\Laravel\Providers\SlashIdServiceProvider"

您已准备就绪!现在访问您的网站中的 /login 并享受您的新 SlashID 登录 :)

配置

此包中有几个配置,您可以在 config/slashid.php 中编辑。您可能需要覆盖的配置是 web_redirect_after_loginweb_redirect_after_logout

登录表单配置

登录表单是 SlashID React SDK 的捆绑版本。因此,所有组件中的选项都可以在这里使用,但请注意,您需要将 camelCase 转换为 kebab-case(见以下示例)。

config/slashid.php 中,选项 login_form_configuration 的默认值如下

// config/slashid.php

return [
    'login_form_configuration' => [
        'factors' => [
            ['method' => 'webauthn'],
            ['method' => 'email_link'],
        ],
        'analytics-enabled',
        // Uncomment to enable the dark theme.
        // 'theme-props' => ['theme' => 'dark'],
    ],
    //.............
];

身份验证方法

例如,如果您想添加密码登录,首先在 SlashID 控制台 > 设置中添加密码选项,然后将配置更改为以下内容

// config/slashid.php

return [
    'login_form_configuration' => [
        'factors' => [
            ['method' => 'webauthn'],
            ['method' => 'email_link'],
            ['method' => 'password'],
        ],
        'analytics-enabled',
        // Uncomment to enable the dark theme.
        // 'theme-props' => ['theme' => 'dark'],
    ],
    //........
];

有关更多信息,请参阅以下文档:https://developer.slashid.dev/docs/access/sdk/interfaces/Types.Factor

登录表单主题

您可以通过覆盖 login_form_configuration 中的 theme-props 选项来选择浅色或深色主题。例如,这将使主题变暗

// config/slashid.php

return [
    'login_form_configuration' => [
        'factors' => [
            ['method' => 'webauthn'],
            ['method' => 'email_link'],
        ],
        'analytics-enabled',
        'theme-props' => ['theme' => 'dark'],
    ],
    //.............
];

您还可以覆盖 React SDK 提供的任何 CSS 变量。例如,要使登录按钮变红,您可以这样做

// config/slashid.php

return [
    //.............
    'login_form_css_override' => [
        '--sid-color-primary' => '#f00',
    ],
    //.............
];

基于组的访问检查路由

您可以使用 slashid_group 中间件将某些路由限制为属于特定组的人员。例如,如果您想创建一个只有“编辑”组内人员可以访问的 /content-management 路由,以及一个只有“管理员”组内人员可以访问的 /admin 路由,您可以这样做

// web.php

Route::get('/content-management', function () {
    // Route that only someone in the group "Editor" can access.
})->middleware('slashid_group:Editor');

Route::get('/admin', function () {
    // Route that only someone in the group "Admin" can access.
})->middleware('slashid_group:Admin');

如果用户未登录,他们将被重定向到登录页面。如果用户已登录,他们将收到一个访问拒绝异常。

⚠️ 注意:组名区分大小写,请确保您使用的是正确的组名。

您还可以在路由检查中组合不同的组!例如,如果您想使 /dashboard 页面可供任何属于“管理员”、“编辑”或“审阅者”组的任何人访问,您可以使用 |OR 联合中组合不同的组名

// web.php

Route::get('/group/Admin-OR-Editor', function () {
    // Route that someone in the group "Admin", OR in the group "Editor", OR in the group "Reviewer" can access.
})->middleware('slashid_group:Admin|Editor|Reviewer');

您还可以使用 &AND 联合中组合组

Route::get('/very-secure-page', function () {
    // Route that is only accessed by someone *both* in the "Admin" and "Editor" groups.
})->middleware('slashid_group:Admin&Editor');

⚠️ 注意:您不能在同一个路由中组合 |&,例如 ->middleware('slashid_group:Admin&Editor|Reviewer') 是一个无效声明,将引发异常。

在自定义代码中的组检查

如果您想在自定义代码中检查用户的组,您可以使用\SlashId\Laravel\SlashIdUser类的任何与组相关的功能,例如:

if ($user->hasGroup('Editor')) {
    // Do things that only an "Editor" user can do.
}

if ($user->hasAnyGroup(['Admin', 'Editor', 'Reviewer'])) {
    // Do things that someone in the group "Admin", OR in the group "Editor", OR
    // in the group "Reviewer" can do.
}

if ($user->hasAllGroups(['Admin', 'Editor'])) {
    // Do things that only someone that is in *both* "Admin" and "Editor" groups
    // can do.
}

// Shows the user groups as a list of strings.
var_dump($user->getGroups());

Blade中的组检查

您还可以使用hasGroup / hasAnyGroup / hasAllGroups方法在Blade模板中构建显示不同内容的模板,具体取决于用户所属的组。

// some-template.blade.php

@if (auth()->user())

    <p>You are logged in</p>

    @if (auth()->user()->hasGroup('Editor'))

        <p>Information Editors can access.</p>

    @endif

    @if (auth()->user()->hasGroup('Admin'))

        <p>Information Admins can access.</p>

    @endif

    @if (auth()->user()->hasAnyGroup(['Admin', 'Editor']))

        <p>Information both Editors & Admins can access.</p>

    @endif

@else

    <p>You are NOT logged in</p>

@endif

Webhooks

请参阅SlashID关于Webhooks的文档

Artisan webhook 命令

要使用webhooks,您需要首先将您的URL注册到SlashID。Webhooks通过API管理,但此包提供了三个Artisan命令来帮助您管理它们。

如何注册webhooks

要为当前网站注册新的webhook,请使用以下命令。您需要为其定义一个唯一的名称,在此示例中,我们使用my_laravel_webhook

php artisan slashid:webhook:register my_laravel_webhook

默认情况下,webhook注册了触发器:PersonDeleted_v1PersonLoggedOut_v1PasswordChanged_v1。您可以指定要注册的触发器,用空格分隔触发器列表

php artisan slashid:webhook:register my_laravel_webhook PasswordChanged_v1 VirtualPageLoaded_v1 AuthenticationFailed_v1

您可以根据需要多次运行slashid:webhook:register,如果已经为该URL注册了webhook,它将被更新,并且触发器列表将被覆盖。

如何在本地测试webhooks

您可以使用如ngrok之类的工具在本地开发环境中测试webhooks,然后使用--base-url选项注册带有代理的webhook。

例如,如果您正在端口8080上运行Laravel,您可以使用以下命令通过ngrok代理您的本地环境:

ngrok http 8000

ngrok命令行将显示代理的数据,例如:

Forwarding                    https://2f45-2804-14c-483-983f-b323-32f2-4714-1609.ngrok-free.app -> https://:8000

然后,您可以使用以下命令将web服务注册到代理URL

php artisan slashid:webhook:register proxied_webhook PasswordChanged_v1 --base-url=https://2f45-2804-14c-483-983f-b323-32f2-4714-1609.ngrok-free.app

如何为其他应用程序注册webhooks

您可以使用Artisan命令将webhooks注册到任何任意URL。

php artisan slashid:webhook:register proxied_webhook PasswordChanged_v1 --webhook-url=https://someotherapplication.example.com/some-arbitrary-url

如何查看现有webhooks

您可以使用以下命令查看注册到您的SlashID组织中的所有webhooks

php artisan slashid:webhook:list

如何删除webhook

您可以通过其ID删除webhook。

php artisan slashid:webhook:delete 065e5237-c1c4-7a96-ab00-783ef0cbd002

要学习webhook ID,请使用slashid:webhook:list命令。

监听事件

收到的任何webhook都将作为Laravel事件提供给开发者。

要在您的Laravel应用程序中监听webhook事件,在应用程序的app/Listeners文件夹中创建一个类。在下面的示例中,我们将其命名为WebhookListener,但您可以按需命名。

// app/Listeners/WebhookListener.php
<?php

namespace App\Listeners;

use SlashId\Laravel\Events\WebhookEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class WebhookListener
{
    /**
     * Handle the event.
     */
    public function handle(WebhookEvent $event): void
    {
        print_r([
            $event->getEventName(),
            $event->getEventId(),
            $event->getTriggerContent(),
        ]);
    }
}

创建监听器类后,您需要通过编辑文件app/Providers/EventServiceProvider.php让Laravel知道它的存在。在$listen属性中添加您的类,例如:

// app/Providers/EventServiceProvider.php
<?php

namespace App\Providers;

use App\Listeners\WebhookListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use SlashId\Laravel\Events\WebhookEvent;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event to listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        WebhookEvent::class => [
            WebhookListener::class,
        ],
    ];

    // ... rest of the class provided by Laravel ...
}

监听器将接收类\SlashId\Laravel\Events\WebhookEvent的事件。它有三个您可以用来提取有关webhook调用信息的方法

  • $event->getEventName()将返回触发器名称,例如AuthenticationFailed_v1,即JSON发送到webhook中的->trigger_content->event_metadata->event_name
  • $event->getEventId()将返回事件ID,例如68a850ca-b2ee-46ce-8592-410813037739,即JSON发送到webhook中的->trigger_content->event_metadata->event_id
  • $event->getTriggerContent()将返回webhook调用的完整内容,即JSON发送到webhook中的->trigger_content

用户迁移

如果您正在现有的Laravel网站上安装SlashID,您可能已经有一个您想要迁移到SlashID数据库的用户基础。这可以通过两个迁移命令轻松完成。

首先,您必须运行Artisan命令php artisan slashid:import:create-script。它将询问您的安装中的用户类,通常为\App\Models\User

$ php artisan slashid:import:create-script

 Please inform the class of the user model [\App\Models\User]:
 >

The Slash ID migration script has been created at /var/www/html/database/slashid/user-migration.php. Please open the file and modify it according to the instructions in it.

将在database/slashid/user-migration.php中创建一个脚本。它看起来像这样:

<?php

use SlashId\Laravel\SlashIdUser;

/** @var \Illuminate\Contracts\Auth\Authenticatable[] */
$laravelUsers = \App\Models\User::all();
$slashIdUsers = [];
foreach ($laravelUsers as $laravelUser) {
    $slashIdUser = new SlashIdUser();
    $slashIdUser
        ->addEmailAddress($laravelUser->email)
        ->setLegacyPasswordToMigrate($laravelUser->getAuthPassword())
        // Uncomment if you want to set the phone number.
        // ->addPhoneNumber($laravelUser->phone_number)
        // Uncomment if you want to set groups.
        // ->setGroups(['Editor'])
        // Uncomment if you want to specify a region for the user.
        // ->setRegion('us-iowa')
        ->setBucketAttributes(\SlashId\Php\PersonInterface::BUCKET_ORGANIZATION_END_USER_NO_ACCESS, [
            // List the user attributes you want to migrate, grouped by bucket.
            'old_id' => $laravelUser->getAuthIdentifier(),
            'firstname' => $laravelUser->firstname,
            'email_verified_at' => $laravelUser->email_verified_at,
            'lastname' => $laravelUser->lastname,
            'username' => $laravelUser->username,
        ]);

    $slashIdUsers[] = $slashIdUser;
}

return $slashIdUsers;

您必须将 user-migration.php 调整为根据您的需求来建模要迁移的数据。该脚本必须返回一个包含您希望批量导入到 SlashID 的所有用户的 \SlashId\Laravel\SlashIdUser 数组。

根据您的需求调整脚本后,运行 php artisan slashid:import:run,例如:

$ php artisan slashid:import:run
+------------------------+---------------+--------+-------+--------+-------------------------------------------------------------------------------------------------------------------------------+
| Emails                 | Phone numbers | Region | Roles | Groups | Attributes                                                                                                                    |
+------------------------+---------------+--------+-------+--------+-------------------------------------------------------------------------------------------------------------------------------+
| rattazzi@example.com   |               |        |       |        | {"end_user_no_access":{"old_id":1,"firstname":"Urbano","email_verified_at":null,"lastname":"Rattazzi","username":"rattazzi"}} |
| nitti@example.com      |               |        |       |        | {"end_user_no_access":{"old_id":2,"firstname":"Francesco","email_verified_at":null,"lastname":"Nitti","username":"nitti"}}    |
| cavour@example.com     |               |        |       |        | {"end_user_no_access":{"old_id":3,"firstname":"Camillo","email_verified_at":null,"lastname":"Cavour","username":"cavour"}}    |
+------------------------+---------------+--------+-------+--------+-------------------------------------------------------------------------------------------------------------------------------+

 Do you want to proceed with importing 3 users? (yes/no) [no]:
 > yes

2 successfully imported users.
1 users failed to import. Check the file /var/www/html/database/slashid/migration-failed-202403271142.csv for errors.

迁移过程中发生的任何错误将以 CSV 格式输出。检查 CSV 以修复错误并重新运行。

覆盖登录表单

Blade 模板以及如何在布局中插入表单

登录表单在两个 Blade 模板中渲染:slashid/login.blade.phpslashid/login-form.blade.php。实际的代码位于 login-form 模板中,login 仅作为包装器,在其周围添加一个 <html> 标签。

因此,如果您想在页面的布局中包裹 /login 中的登录表单,您可以覆盖 login 模板。所以

首先,将 vendor/slashid/laravel/resources/views/login.blade.php 复制到 resources/views/vendor/slashid/login.blade.php,然后根据您的需求编辑文件。例如,如果您有一个 <x-app-layout> 组件,您的模板可以是

// resources/views/vendor/slashid/login.blade.php
<x-app-layout>
    @include('slashid::login-form')
</x-app-layout>

在大多数情况下,您不需要覆盖 login-form.blade.php

使用自定义 JavaScript

Laravel 包附带了一个 SlashID React SDK 的捆绑包和位于 vendor/slashid/laravel/public/slashid.laravel-web-login.js 的一个小型 JavaScript Glue 代码片段。

您可能想要覆盖捆绑的 React SDK 来编译您自己的 React 登录表单实现。如果是这样,将 config/slashid.php 中的选项 login_form_override_bundled_javascript 更改为 true 以防止加载捆绑的 React SDK。

或者,您可能想要覆盖 Glue 代码,在登录后包含自定义操作。如果是这样,将 config/slashid.php 中的选项 login_form_override_javascript_glue 更改为 true 以防止加载 Glue 代码。

在这两种情况下,您负责自己加载您的自定义代码。