slashid / laravel
SlashID 集成包用于 Laravel。
Requires
- php: ^8.1
- slashid/php: ^1.0.2
Requires (Dev)
- laravel/framework: ^10
- laravel/pint: ^1.14
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.5
This package is not auto-updated.
Last update: 2024-09-20 13:38:24 UTC
README
安装
- 使用 composer 安装 Laravel 的 SlashID 包
composer require slashid/laravel
- 编辑您的环境文件
.env
,在文件末尾添加以下变量SLASHID_ENVIRONMENT
,可以是sandbox
或production
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
- 运行以下 artisan 命令以发布资源
php artisan vendor:publish --provider="SlashId\Laravel\Providers\SlashIdServiceProvider"
您已准备就绪!现在访问您的网站中的 /login
并享受您的新 SlashID 登录 :)
配置
此包中有几个配置,您可以在 config/slashid.php
中编辑。您可能需要覆盖的配置是 web_redirect_after_login
和 web_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
Artisan webhook 命令
要使用webhooks,您需要首先将您的URL注册到SlashID。Webhooks通过API管理,但此包提供了三个Artisan命令来帮助您管理它们。
如何注册webhooks
要为当前网站注册新的webhook,请使用以下命令。您需要为其定义一个唯一的名称,在此示例中,我们使用my_laravel_webhook
。
php artisan slashid:webhook:register my_laravel_webhook
默认情况下,webhook注册了触发器:PersonDeleted_v1
、PersonLoggedOut_v1
和PasswordChanged_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.php
和 slashid/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 代码。
在这两种情况下,您负责自己加载您的自定义代码。