libaro / miqey-client

一个将 MiQey 集成到您应用程序的包

v1.0.7 2024-09-16 07:56 UTC

This package is auto-updated.

Last update: 2024-09-16 07:57:39 UTC


README

Latest Version on Packagist Total Downloads

MiQey 客户端 Laravel 扩展包简化了 MiQey 功能集成到您的 Laravel 项目中。MiQey 通过生成签名请求、通过二维码或短信管理用户响应,并无缝地将用户登录到您的项目,以实现安全的登录流程。

安装

您可以通过 composer 安装此包

composer require libaro/miqey-client

发布配置文件

php artisan vendor:publish --provider="Libaro\MiQey\MiQeyServiceProvider" --tag="config"

用法

miQey-client 包负责与 miQey-service 通信以处理用户身份验证。您应该做的第一件事是将以下代码添加到您的登录页面

const pusherKey = 'your pusher key';
const subChannel = 'signRequest_{generated_code_from_MiQey}';
const authEndpoint = '/miqey/validate';

var pusher = new Pusher(pusherKey, {
    cluster: 'eu'
});

var channel = pusher.subscribe(subChannel);
channel.bind('sign-request-received', function (data) {
    window.location.href = authEndpoint + '?token=' + data.token
});

当您的应用程序接收到 '用户认证'-webhook 回调时,miQey-client 将发出一个 socket 事件,该事件将被此脚本中的监听器捕获。接收到 socket 事件后,您的登录页面将调用 miQey-client 的 ValidationController,根据其电话号码登录用户。电话号码通过服务器缓存中的 token 接收。

通过这段代码的简单插入,您就可以充分利用 miQey 的全部功能!

生成的文件

下面是包生成的供应商文件及其在将 MiQey 集成到您的项目中的作用的详细说明。

config/miqey.php

安装 miQey-client 会生成一个配置文件来存储与 MiQey 认证服务通信所需的凭据和端点。它包含以下键,这些键应指向环境文件中正确的值

  • api_key:将服务集成到您的项目中的个人 API 密钥。您可以从 MiQey 平台上对应应用程序的设置页面获取 API 密钥(https://secureid.digitalhq.com/app/{application_id}/settings)。

  • webhook_secret:MiQey 客户端使用此值来解密包含在 'authenticated'-回调中的 webhook 签名。这保护了 MiQey 与您的应用程序之间的通信免受中间人攻击。您可以在 MiQey 平台上对应应用程序的设置页面生成 webhook 密钥(https://secureid.digitalhq.com/app/{application_id}/settings)。

  • webhook_endpoint:MiQey 必须向其发送 'authenticated'-webhook 回调的端点。您可以在 MiQey 平台上对应应用程序的设置页面设置此 URL(https://secureid.digitalhq.com/app/{application_id}/settings)。理想情况下,URL 应具有以下结构:{your_application_base_url}/api/sign/webhook

  • user_model:您项目中 User 模型的路径。MiQey-client 使用此模型在您的应用程序中验证用户,因此您不再需要自行验证用户。默认为 '\App\Models\User'。

return [
    'api_key' => env('MIQEY_API_KEY'),

    'webhook_secret' => env('MIQEY_WEBHOOK_SECRET'),

    'webhook_endpoint' => env('MIQEY_WEBHOOK_ENDPOINT'),

    'user_model' => env('MIQEY_USER_MODEL', '\App\Models\User'),
];

routes/routes.php

miQey 为您的项目添加了两个新路由,以便后端服务可以访问您的应用程序

  • POST {webhook_endpoint},默认 /miqey/webhook:这是 MiQey 在 MiQey 后端中签名签名请求时向其发送 webhook 的端点。您可以在 MiQey 门户中对应应用程序的设置页面更改此 webhook。

  • GET /miqey/validate: 当您的前端接收到来自后端的socket事件,表示用户已认证,它将重定向到该端点,这将调用ValidationController以将用户登录到您的应用程序。

src/Events/SignSmsRequestReceived

SignSmsRequestReceived是当miQey客户端从miQey-backend服务接收到“用户认证”回调时发出的socket事件。它传递一个令牌,可以用来从您的后端缓存中检索用户的手机号码。

class SignSmsRequestReceived implements ShouldBroadcastNow
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(
        public string $code,
        public string $token
    ) {
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array
     */
    public function broadcastOn(): array
    {
        return ["signRequest_$this->code"];
    }

    public function broadCastAs(): string
    {
        return 'sign-request-received';
    }
}

src/Handlers/WebhookHandler.php

当向应用程序的webhook_endpoint发送“用户认证”回调时,将调用WebhookHandler。首先,它通过使用miQey-config文件中的webhook secret解密header中的签名来验证webhook的真实性。当验证原点后,它从回调体中获取用户的手机号码和签名代码。将phone_number存入缓存以防止将其暴露给应用程序的前端。创建一个新的令牌作为缓存键。这个令牌,连同签名代码一起,随上述段落中描述的socket事件传递,该事件在该点触发以让登录页面知道要重定向。

class WebhookHandler
{
    public function __invoke(WebhookReceivedRequest $request)
    {
        $data = $request->validated();

        $signature = $request->header('Signature');

        $calculatedSignature = hash_hmac('sha256', $request->getContent(), config('miqey-login.webhook_secret'));

        if (! hash_equals($signature, $calculatedSignature)) {
            return response()->json(status: 401);
        }

        $phone = $data['phone'];
        $code = $data['code'];

        $token = Str::random(32);

        Cache::put($token, $phone, now()->addSeconds(10));

        event(new SignSmsRequestReceived($code, $token));

        $now = now();

        for($i = 0; $i < 10; $i++) {
            dispatch(function() use ($token, $code) {
                event(new SignSmsRequestReceived($code, $token));
            })->delay($now->addSeconds($i+1));
        }

        return response()->json(status: 204);
    }
}

src/Http/Controllers/ValidationController.php

ValidationController是miQey认证流程的最后一步。当调用此控制器时,它从服务器缓存中获取已认证用户的手机号码。然后,使用您的miQey配置文件中的路径解析用户模型,并查询该模型以通过phone_number获取用户。最后,它将用户登录到您的应用程序,并重定向到已认证的根url。

class ValidationController extends Controller
{
    public function __invoke(Request $request)
    {
        $hasToken = Cache::has($request->get('token'));

        if (! $hasToken) {
            // todo: change to exception?
            abort(403, 'token mismatch');
        }

        $phoneNumber = Cache::pull($request->get('token'));

        $userClass = config('miqey.user_model');
        $user = $userClass::query()
            ->where('phone_number', '=', $phoneNumber)
            ->first();

        if (is_null($user)) {
            // todo: change to exception?
            abort(403, 'user not found');
        }

        Auth::login($user);

        return redirect()->to(App\Providers\RouteServiceProvider\RouteServiceProvider::HOME);
    }
}

测试

composer test

变更日志

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

安全

如果您发现任何与安全相关的问题,请通过电子邮件github@libaro.be联系,而不是使用问题跟踪器。

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件