goodid/goodid-php-sdk

GoodID SDK for PHP

5.1.1 2024-07-15 13:15 UTC

README

Build Status

GoodID SDK for PHP

此存储库包含我们的开源PHP SDK,允许您收集、解密和验证从用户接收到的数据。

注意:此版本的GoodID SDK for PHP需要PHP 5.6或更高版本。

安装

您可以使用Composer安装GoodID PHP SDK。将GoodID PHP SDK包添加到您的composer.json文件中。

{
    "require": {
        "goodid/goodid-php-sdk": "~5.0"
    }
}

先决条件

要为用户提供GoodID登录,您首先需要在GoodID上注册。您将收到以下内容

  • GoodID移动应用程序下载链接
  • 客户端ID
  • 客户端密钥
  • 默认密钥对
  • 建议的声明集

此时,您还有机会生成自己的密钥对并将公钥发送到GoodID。

下载GoodID应用程序

Alt text Alt text

GoodID登录流程

这是对GoodID登录流程的简要介绍,让您了解需要实现哪些端点(在“要实现的端点”部分详细说明)的目的。

GoodID登录流程概述

  1. JavaScript SDK只负责渲染“使用GoodID登录”按钮。了解更多
  2. 当用户点击“使用GoodID登录”按钮时,用户代理将被导航到GoodID登录启动端点
  3. GoodID登录启动端点构建“授权请求”,并将带有请求的URL重定向到GoodID授权EP。
  4. 用户在GoodID移动应用程序中接收请求并做出回应。
  5. 最后,用户将被重定向到您的重定向URI(着陆页),带有“code”和“state”参数,这些参数由GoodID PHP SDK用于收集、解密和验证用户提供的信息。

要实现的端点

GoodID登录启动端点

所谓的GoodID登录启动端点是GoodID的指定端点。它类似于OpenID Connect登录启动端点,并负责生成OpenID身份验证请求。

您无需处理GET/POST参数,也不需要编写响应,这一切都是由代码片段中实例化的GoodID端点自动完成的。

// GoodID Login Initiation Endpoint (e.g. goodid-endpoint.php)

// Load the SDK and other dependencies
require_once __DIR__ . '/vendor/autoload.php';

use GoodID\Authentication\GoodIDEndpointFactory;
use GoodID\Helpers\GoodIDPartnerConfig;
use GoodID\Helpers\Key\RSAPrivateKey;
use GoodID\Helpers\OpenIDRequestSource\OpenIDRequestObject;
use GoodID\Helpers\Request\IncomingRequest;
use GoodID\ServiceLocator;

// -- Basic configuration --
$clientId = 'YOUR-CLIENT-ID';
$clientSecret = 'YOUR-CLIENT-SECRET';
$redirectUri = 'YOUR-REDIRECT-URI';
$scopes = array('YOUR-SCOPES'); // It can be an empty array
$claims = 'YOUR-CLAIMS-JSON-STRING';
$sigPrivKeyPEM = "YOUR-SIG-PRIV-KEY-PEM-STRING";
$sigPrivKeyKeyId = 'KEY-ID-OF-YOUR-SIG-PUB-KEY-ON-JWKS-URI';
$encPrivKeyPEM = "YOUR-ENC-PRIV-KEY-PEM-STRING";
$encPrivKeyKeyId = 'KEY-ID-OF-YOUR-ENC-PUB-KEY-ON-JWKS-URI';
// -- End of Basic configuration --

// -- Set session data handler OPTION 1 -- 
// You can use our default session data handler. 
// In this case you need to start the session first.
session_start();
$serviceLocator = new ServiceLocator();

// -- Set session data handler OPTION 2 -- 
// Or you can add your own session data handler
// by defining a class which implements \GoodID\Helpers\SessionDataHandlerInterface
// Add that to the $serviceLocator.
$serviceLocator = new ServiceLocator();
$serviceLocator->setSessionDataHandler(new CustomSessionDataHandler());

$encKey = new RSAPrivateKey($encPrivKeyPEM, array('use' => 'enc', 'kid' => $encPrivKeyKeyId));
$sigKey = new RSAPrivateKey($sigPrivKeyPEM, array('use' => 'sig', 'kid' => $sigPrivKeyKeyId));

$goodidEndpoint = GoodIDEndpointFactory::createInitiateLoginEndpoint(
    $serviceLocator,
    new GoodIDPartnerConfig($clientId, $clientSecret, $sigKey, $encKey),
    new OpenIDRequestObject($claims, $scopes),
    $redirectUri,
    new IncomingRequest()
);

$goodidEndpoint->run();

重定向URI(着陆页)

用户使用GoodID移动应用程序响应请求并重定向到您的所谓重定向URI。SDK收集、解密和验证响应。

// Redirect URI / landing page

require_once __DIR__ . '/vendor/autoload.php';

use GoodID\Authentication\GoodIDEndpointFactory;
use GoodID\Helpers\GoodIDPartnerConfig;
use GoodID\Helpers\Key\RSAPrivateKey;
use GoodID\ServiceLocator;

// -- Basic configuration --
$clientId = 'YOUR-CLIENT-ID';
$clientSecret = 'YOUR-CLIENT-SECRET';
$securityLevel = 'YOUR-SECURITY-LEVEL'; // 'NORMAL' or 'HIGH'
$sigPrivKeyPEM = "YOUR-SIG-PRIV-KEY-PEM-STRING";
$sigPrivKeyKeyId = 'KEY-ID-OF-YOUR-SIG-PUB-KEY-ON-JWKS-URI';
$encPrivKeyPEM = "YOUR-ENC-PRIV-KEY-PEM-STRING";
$encPrivKeyKeyId = 'KEY-ID-OF-YOUR-ENC-PUB-KEY-ON-JWKS-URI';
// -- End of Basic configuration --

// -- Set session data handler OPTION 1 -- 
// You can use our default session data handler. 
// In this case you need to start the session first.
session_start();
$serviceLocator = new ServiceLocator();

// -- Set session data handler OPTION 2 -- 
// Or you can add your own session data handler
// by defining a class which implements \GoodID\Helpers\SessionDataHandlerInterface
// Add that to the $serviceLocator.
$serviceLocator = new ServiceLocator();
$serviceLocator->setSessionDataHandler(new CustomSessionDataHandler());

$encKey = new RSAPrivateKey($encPrivKeyPEM, array('use' => 'enc', 'kid' => $encPrivKeyKeyId));
$sigKey = new RSAPrivateKey($sigPrivKeyPEM, array('use' => 'sig', 'kid' => $sigPrivKeyKeyId));

try {
    $gidResponse = GoodIDEndpointFactory::getResponse(
        $serviceLocator, 
        new GoodIDPartnerConfig($clientId, $clientSecret, $sigKey, $encKey, $securityLevel)
    );
    
    if ($gidResponse->isSuccessful()) {
        // Subject identifier
        $subjectIdentifier = $gidResponse->getSub();

	if ($securityLevel === 'HIGH') {
	    $userId = $gidResponse->getUserId();
	    $deviceId = $gidResponse->getDeviceId();
	}

        // The data provided by the user
        $claims = $gidResponse->getClaims()->toArray();
    
        // Now begins the substantial part of the job:
        // You can do your custom validation of claims.
        // You can log in (or register) the user:
        // Read/write your DB, regenerate session id, etc.
        // Good luck :-)
    } else {
        $error = $gidResponse->getError();
        $errorDescription = $gidResponse->getErrorDescription();
        // The login has failed with an OpenID Authentication Error Response
        // For example the user pressed cancel in the app
    }
} catch(\Exception $e) {
    // The login has failed with an exception
    // The identity of the user cannot be verified
}

杂项

以下步骤可能在集成的某些步骤中很有用。

生成自己的密钥对

如果您希望生成自己的密钥对,可以通过以下方式实现,使用openssl为Ubuntu安装openssl

sudo apt-get install openssl

生成密钥对

openssl genrsa -out client-enc_key.pem 2048
openssl rsa -in client-enc_key.pem -pubout > client-enc_key.pub
openssl genrsa -out client-sig_key.pem 2048
openssl rsa -in client-sig_key.pem -pubout > client-sig_key.pub

请发送以下内容给我们

  • 新的公钥密钥对(.pub文件)。
  • 由新密钥签名的请求对象。

生成JWKs URI的内容

您的JWKs URI包含您的公钥(签名和加密)的JSON格式(JWK)。

如果您还没有JWKs URI,您可以像这样生成其内容

use GoodID\Helpers\Key\JwkSetGenerator;
use GoodID\Helpers\Key\RSAPublicKey;

$sigPrivKeyPEM = "YOUR-SIG-PRIV-KEY-PEM-STRING";
$sigPrivKeyId = 'KEY-ID-OF-YOUR-SIG-PUB-KEY-ON-JWKS-URI';
$encPrivKeyPEM = "YOUR-ENC-PRIV-KEY-PEM-STRING";
$encPrivKeyId = 'KEY-ID-OF-YOUR-ENC-PUB-KEY-ON-JWKS-URI';

$encKey = new RSAPrivateKey($encPrivKeyPEM, array('use' => 'enc', 'kid' => $encPrivKeyId));
$sigKey = new RSAPrivateKey($sigPrivKeyPEM, array('use' => 'sig', 'kid' => $sigPrivKeyId));

$jwkSetGenerator = new JwkSetGenerator();
$jwkSetGenerator->addKey($sigKey);
$jwkSetGenerator->addKey($encKey);

$jwkSetGenerator->run();