rublon/rublon-sdk-php

无需繁琐的设置,即可实现基于电子邮件的即时账户安全双因素认证;可选移动应用以增强安全性;无需令牌

This package is auto-updated.

Last update: 2024-09-14 15:52:58 UTC


README

目录

  1. 概述
  2. 使用场景
  3. 支持的认证方法
  4. 开始之前
  5. 配置
  6. Laravel 配置
  7. 故障排除

概述

Rublon PHP SDK 库 是用 PHP 编写的 Rublon API 的客户端实现。该库包括将 Rublon API 的 GUI 嵌入基于 HTML 的环境中的方法。Rublon PHP SDK 为 Rublon API 的 REST 接口提供了一个便捷的 PHP 编程语言界面。

使用场景

Rublon 通过提示用户使用额外的认证方法(如移动推送)进行认证,增加了额外的安全层。即使恶意行为者妥协了用户的密码,黑客也无法登录用户的账户,因为第二个安全因素将阻止他们。

Rublon 可以在以下两个用例中增加额外的安全层

  1. 当用户登录系统时(用户输入正确密码后)
  2. 当用户进行安全敏感的交易时(如更改密码或进行货币转账)

当用户登录系统时,第二个认证因素应该在以下情况下启动:

  • 用户已成功完成第一个认证因素(例如,输入正确的密码)
  • 收集了用户的唯一用户名和电子邮件地址

支持的认证方法

  • 移动推送 - 在 Rublon 验证器移动应用上显示的推送通知上轻触以批准认证请求。
  • 移动密码(TOTP)- 使用 Rublon 验证器移动应用或第三方认证器应用(如 Google Authenticator 或 Microsoft Authenticator)输入 TOTP 代码(基于时间的单次密码)。
  • 短信密码 - 输入发送到您的手机号码的短信中的验证码。
  • 二维码 - 使用 Rublon 验证器移动应用扫描二维码。
  • 电子邮件链接 - 点击发送到您的电子邮件地址的验证链接。
  • WebAuthn/U2F 安全密钥 - 将安全密钥插入电脑的 USB 端口并触摸它。
  • YubiKey OTP - 插入 YubiKey 并轻触以自动将 OTP 输入到文本字段。

开始之前

在将 Rublon PHP SDK 库集成到代码之前,您必须在 Rublon 管理控制台中创建一个应用程序。我们还建议您安装 Rublon 验证器移动应用以用于移动推送、移动密码和二维码认证方法。

在 Rublon 管理控制台中创建应用程序

  1. 注册Rublon管理控制台。 这里是如何操作的
  2. 在Rublon管理控制台中,转到应用选项卡,然后点击添加应用
  3. 为您的应用输入一个名称,然后将类型设置为使用PHP SDK的定制集成
  4. 点击保存以在Rublon管理控制台中添加新的PHP SDK应用。
  5. 复制并保存系统令牌密钥的值。您稍后需要这些值。

可选:安装 Rublon 验证器

为了提高多因素认证(MFA)的安全性,建议最终用户安装Rublon Authenticator移动应用。

下载Rublon Authenticator

安装移动应用后,用户可以使用以下认证方法进行认证

在某些情况下,用户可能不想在手机上安装任何额外的应用。还有一些用户拥有不支持现代移动应用的老旧手机。这些用户可以使用以下认证方法之一进行认证

配置

按照以下步骤配置Rublon PHP SDK。

INFO:初始假设

假设有一个超级全局会话关联数组$_SESSION。它可以访问一个对象,该对象存储当前登录用户的用户数据。

$_SESSION数组将在本文件的后续PHP代码示例中使用。

INFO:修改库

Rublon类实现了一些公共方法,当需要时,可以使用类继承来覆盖这些方法。

我们强烈建议您不要修改库的任何部分,因为这通常会导致库更新时的困难。如果您需要更改RublonRublonCallback类的流程或内部结构,请毫不犹豫地根据您的需求创建子类。

初始化库

要初始化Rublon PHP SDK库,您需要实例化一个Rublon类对象。其构造函数需要三个参数。

示例PHP代码

  require_once "libs/Rublon/Rublon.php";

  $rublon = new Rublon(
     "D166A6E9996A40F0A88252432FA5E490",
     "913eda929c96cf52141b39f5717e25",
     "https://core.rublon.net"
  );

执行认证

Rublon::auth()方法使用用户名检查用户的安全状态,并返回用户应在网页浏览器中重定向到的URL地址。

示例PHP代码

    /**
     * An example method used to log the user in (integrated system's method)
     *
     * @param string $login
     * @param string $password
     */
    function login($login, $password) {
        if (loginPreListener()) {
            if ($user = authenticate($login, $password)) {
                // The user has been authenticated.
                $_SESSION["user"] = $user;
                loginPostListener();
            }
        }
    }

    /**
     * Listener (hook) invoked after a successful first factor user authentication,
     * implemented for Rublon integration purposes.
     */
    function loginPostListener() {
        // Make sure that the user is not logged-in
        unset($_SESSION['user']);

        $rublon = new Rublon(
            "D166A6E9996A40F0A88252432FA5E490",
            "913eda929c96cf52141b39f5717e25",
            "https://core.rublon.net"
        );

        try { // Initiate a Rublon authentication transaction
            $authUrl = $rublon->auth(
                $callbackUrl = "http://example.com?rublon=callback",
                $_SESSION["user"]["login"], // Username
                $_SESSION["user"]["email"] // User email
            );

            if (!empty($authUrl)) { // User protection is active
                // Redirect the user's web browser to Rublon servers to verify the protection:
                header('Location: ' . $authUrl);
            } else {
                // User is not protected by Rublon, so bypass the second factor.
                header('Location: index.php');
            }
        } catch (UserDeniedException $e) {
            // Access Denied
            header('Location: ./');
        } catch (UserBypassedException $e) {
            // User bypassed
            header('Location: ./');
        } catch (RublonException $e) {
            // An error occurred
            die($e->getMessage());
        }
    }

注意:请确保您的代码检查用户是否未登录。用户应在Rublon认证成功后才能登录。

验证配置

Rublon::checkApplication()方法验证配置的有效性。您的应用程序应该在每次更改或保存配置时调用此方法。配置更改可以是更改系统令牌或密钥等。

Rublon::checkApplication()可能抛出以下异常之一

  • ApplicationNotFoundException - 无效的系统令牌
  • InvalidSignatureException - 无效的密钥
  • UnsupportedVersionException - 应用程序的版本不正确

完成认证

认证成功后,Rublon将用户重定向到回调URL。回调流程将继续并最终完成认证过程。

输入参数

回调URL将接收输入参数(查询字符串)本身。

注意:如果回调URL已设置为,例如http://example.com/auth,则参数将附加到URL地址

http://example.com/auth?rublonState=ok&rublonToken=Kmad4hAS...

注意:如果您想以不同的方式构造回调URL(例如,使用mod_rewrite),则可以使用元标记设置回调URL的模板,如下所示

http://example.com/auth/%rublonState%/%rublonToken%

处理认证结果

回调调用后,您需要实例化一个 RublonCallback 类对象,以正确完成身份验证过程。

接下来,调用 RublonCallback::call() 方法。它接受两个参数

示例PHP代码

以下是一个示例,说明如何在回调中使用 RublonCallback

  $rublon = new Rublon(
     "D166A6E9996A40F0A88252432FA5E490",
     "913eda929c96cf52141b39f5717e25",
     "https://code.rublon.net"
  );
  
  try {
     $callback = new RublonCallback($rublon);
     $callback->call(
        $successHandler = function($username, RublonCallback $callback) {
           // The user is finally logged in
           $_SESSION["user"] = $username;
        },
        $cancelHandler = function(RublonCallback $callback) {
           // Cancel the authentication process
           header("Location: ./login");
           exit;
        }
     );
     
     // The authentication process was successful, redirect to the main page:
     header("Location: ./");
     exit;
  } catch (RublonException $e) {
     // Please handle this error in the better way
     die($e->getMessage());
  }

Laravel 配置

此 Laravel 配置示例使用的是 Breeze 开发套件。

  1. 创建应用程序并安装 Breeze 后,您需要添加 Rublon PHP SDK

    composer require Rublon/rublon-sdk-php

  2. 将这些添加到 .env 文件中

    RUBLON_TOKEN="您的 rublon token"

    RUBLON_KEY="您的 rublon key"

    RUBLON_URL="https://core.rublon.net"

  3. 在 routes/auth.php 中为 Rublon 回调创建新的路由

    Route::get('rublon-callback', [AuthenticatedSessionController::class, 'rublonCallback'])>name('rublon-callback');

  4. 修改控制器中的 store 方法

    Http/Controllers/Auth/AuthenticatedSessionController.php

      public function store(LoginRequest $request)
      {
         $request->authenticate();
    
         $rublon = new Rublon(
            env('RUBLON_TOKEN'),
            env('RUBLON_KEY'),
            env('RUBLON_URL'),
         );
    
         try { // Initiate a Rublon authentication transaction
            $url = $rublon->auth(
               $callbackUrl = url('/rublon-callback'),
               Auth::user()->email, // User email used as username
               Auth::user()->email  // User email
            );
    
            if (!empty($url)) {
               Auth::logout();
               return redirect()->away($url);
            } else {
               // User is not protected by Rublon, so bypass the second factor.
               $request->session()->regenerate();
               return redirect()->to('dashboard');
            }
         } catch (UserBypassedException $e) {
            return redirect()->to('login');
         } catch (RublonException $e) {
            // An error occurred
            die($e->getMessage());
         }
    
         return redirect()->intended(RouteServiceProvider::HOME);
      }
    
  5. 为 Rublon 回调添加新方法

      public function rublonCallback(Request $request)
      {
         $rublon = new Rublon(
            env('RUBLON_TOKEN'),
            env('RUBLON_KEY'),
            env('RUBLON_URL'),
         );
    
         try {
            $callback = new RublonCallback($rublon);
            $request->session()->regenerate();
            $callback->call(
               $successHandler = function($username, RublonCallback $callback) {
                  $user = User::where('email', $username)->firstOrFail();
                  Auth::login($user);
                  if (Auth::check()) {
                     return redirect()->to('dashboard');
                  } else {
                     return redirect()->to('login');
                  }
               },
               $cancelHandler = function(RublonCallback $callback) {
                  return redirect()->to('login');
               }
            );
    
            return redirect()->to('dashboard');
         } catch (Rublon Exception $e) {
            die($e->getMessage());
         }
    
         return redirect()->to('dashboard');
      }
    

故障排除

如果您在 Rublon 集成过程中遇到任何问题,请联系 Rublon 支持