cidaas/oauth2-cidaas

Cidaas OAuth 2.0 和 OpenID connect 客户端 SDK

v1.3.3 2024-02-07 05:18 UTC

This package is auto-updated.

Last update: 2024-09-07 06:25:59 UTC


README

Logo

关于cidaas

cidaas 是一种快速且安全的云身份与访问管理解决方案,它标准化了重要内容,简化了复杂内容。

功能包括

  • 基于 OAuth 2.0、OpenID Connect、SAML 2.0 的单点登录 (SSO)
  • 多因素认证,包括 TOTP 和 FIDO2 等超过 14 种认证方法
  • 无密码认证
  • 社交登录(例如 Facebook、Google、LinkedIn 等)以及企业身份提供者(例如 SAML 或 AD)
  • 机器到机器 (M2M) 和物联网 (IoT) 中的安全性

Cidaas SDK for PHP

要求

确保您在开发机器上已安装以下所有先决条件

  • PHP 版本 7.4.0 或更高版本
  • 下载并安装 composer

安装

为了使用此 SDK,您需要执行以下步骤

  1. 将 cidaas 仓库添加到您的 composer.json 配置文件中
    "repositories": [
      {
        "type": "vcs",
        "url": "https://github.com/Cidaas/cidaas-sdk-php.git"
      }
    ]
    
  2. 使用 composer 安装 SDK 依赖项
    composer require "cidaas/oauth2-cidaas:<tag / branch>", e.g. "cidaas/oauth2-cidaas:dev-master"
    

集成

先决条件

在开始集成此 SDK 之前,您需要以下信息

  • 基本 URL - cidaas 服务器的 URL
  • 客户端 ID - 由 cidaas 颁发以识别您的应用程序
  • 客户端密钥 - 由 cidaas 颁发以识别您的应用程序
  • 重定向 URI - 登录成功后要重定向到的 URI

除了这些数据之外,您还应该阅读 https://docs.cidaas.de 中的文档,特别关注集成章节。

请注意,运行您的 PHP 应用程序的 Web 服务器需要直接访问上述基本 URL。如果这不可能实现,请考虑使用浏览器端集成的 JavaScript SDK。

基本通信提供者

所有通信都使用 PHP 类 Cidaas\OAuth2\Client\Provider\Cidaas(以下章节中称为 provider)。为了能够使用此提供者,您需要使用上述先决条件数据实例化它。

<?php
$provider = new Cidaas('https://yourcidaasinstance.cidaas.de', 'client id', 'client secret', 'https://yourwebsite/redirectAfterLogin');
?>

除了这些必需的参数之外,还有两个可选的构造函数参数

  • handler:用于干扰正在执行的 http 连接
  • debug:启用调试模式

在构造过程中,会执行一个 http 调用来从服务器读取基本配置数据。

托管登录页面集成

为了集成托管登录页面,您可以仅实现一个简单的按钮,该按钮在点击时调用登录方法。默认情况下,pkce 流已被禁用。要启用 pkce 流,您必须通过在函数参数中提供值 true 来启用标志 $pkceEnabled。

<?php
    $provider->loginWithBrowser();
?>

登录成功后,浏览器会重定向到您选择的重定向 URI(请参阅先决条件)。使用 loginCallback 方法可以检索用于检索访问令牌和刷新令牌的授权代码。

<?php
$parameters = $provider->loginCallback();
if (array_key_exists('code', $parameters)) {
    $loginResultCode = $parameters['code'];     
}
?>

构建自己的登录页面

您可以构建自己的登录页面并使用直接登录机制。为了访问登录方法,您需要首先检索 requestId。

<?php
    try {
        $loginResult = $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
            return $provider->loginWithCredentials($username, 'email', $password, $requestId);
        })->wait();
        $loginResultCode = $loginResult['data']['code'];
    } catch (ClientException $exception) {
        $errorBody = json_decode($exception->getResponse()->getBody(), true);
        $passwordErrorMessage = $errorBody['error']['error_description'];
    }
?>

登录后获取令牌

使用登录结果代码,您可以使用带有 AuthorizationCode 授权类型的 getAccessToken 方法获取访问令牌和刷新令牌。

<?php
    $accessTokenResponse = $provider->getAccessToken(GrantType::AuthorizationCode, $loginResultCode)->wait();
    $accessToken = $accessTokenResponse['access_token'];
    $refreshToken = $accessTokenResponse['refresh_token'];
?>

构建自己的注册页面

为了构建自己的注册页面,您可以使用带 requestId 和 locale 的 getRegistrationSetup 来检索所需字段。

<?php
    $registrationResponse = $provider->getRequestId()->then(function ($requestId) {
        return $provider->getRegistrationSetup($requestId, $locale);
    })->wait();
    $registrationFields = $registrationResponse['data'];
?>

使用这些字段和另一个 requestId,然后可以 register 新客户。

<?php
try {
    $registrationResponse = $provider->getRequestId()->then(function ($requestId) {
        return $provider->register($fields, $requestId);
    })->wait();
} catch (ClientException $exception) {
    $errorMessage = json_decode($exception->getResponse()->getBody())['error']['error'];
}
?>

通过刷新令牌获取访问令牌

为了通过给定的刷新令牌获取新的访问令牌,您还可以使用带有 GrantType RefreshToken 的方法 getAccessToken

<?php
    $accessToken = $provider->getAccessToken(GrantType::RefreshToken, '', $refreshToken)->then(function ($response) {
        return $response['access_token'];
    })->wait();
?>

注销

为了执行注销,您需要一个访问令牌。使用此令牌,您可以进行注销。

<?php
    $provider->logout($accessToken);
?>

托管注册页面的集成

为了集成托管注册页面,您可能只需实现一个简单的按钮,该按钮在点击时本身会调用注册方法。该函数接受以下参数

<?php
    $provider->registerWithBrowser();
?>

注册成功后,浏览器将被重定向到登录页面,您可以使用注册的详细信息进行登录。重定向有时会根据客户端的配置而有所不同。

社交登录页面的集成

为了集成社交登录重定向,您可能只需实现一个简单的按钮,该按钮在点击时会调用登录方法。为了访问登录方法,您首先需要检索 requestId。该函数需要一个提供者名称(例如:google、facebbok)和 requestId 作为功能参数,并且可以可选地添加更多查询参数到请求 URL 中。

<?php
    $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $provider->loginWithSocial('google', $requestId);
    })
?>

这将重定向到社交提供者的登录页面。登录成功后,浏览器将被重定向到您选择的 redirectUri(请参阅先决条件)。

社交注册页面的集成

为了集成社交注册重定向,您可能只需实现一个简单的按钮,该按钮在点击时会调用注册方法。为了访问注册方法,您首先需要检索 requestId。该函数需要一个提供者名称(例如:google、facebbok)和 requestId 作为功能参数,并且可以可选地添加更多查询参数到请求 URL 中。

<?php
    $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $provider->registerWithSocial('google', $requestId);
    })
?>

这将重定向到社交提供者的注册页面。注册成功后,您可以调用函数 loginWithSocial 开始使用社交提供者登录到您的 cidaas 客户端。

启动多因素认证

要启动多因素认证,请使用函数 initiateMFA。您首先需要检索 requestId。允许的类型如下列所示

    EMAIL
    SMS
    IVR
    BACKUPCODE
    SECURITY_QUESTION
    TOTP
    PATTERN
    PUSH
    FACE
    TOUCHID
    VOICE
    FIDOU2F
    FIDO2
    SEALONE
    PASSWORD
<?php
    $resp = $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $params = [
            "email" => 'account@cidaas.de'
            "request_id" => $requestId,
            "usage_type" => "MULTIFACTOR_AUTHENTICATION"
        ]
        $resp = $provider->intiateMFA('EMAIL', $params)->wait();
    })
?>

该函数中使用的 api 返回的响应如下。您需要从响应中获取 exchange_id 和 sub 以完成通过调用函数 authenticateMFA 的认证过程。

{
	"success": true,
	"status": 200,
	"data": {
		"exchange_id": {
			"exchange_id": "a64782cd-d136-4fc3-a879-3afb4feb7453",
			"expires_at": "2023-11-20T07:37:01.439Z",
			"_id": "0d69a2b7-4a2c-4776-97bf-09da5d243e02",
			"createdTime": "2023-11-20T07:07:01.440Z",
			"updatedTime": "2023-11-20T07:07:01.440Z",
			"__ref": "58dfddbc8e3777f5:2a4e7a910c19bc67:58dfddbc8e3777f5:0",
			"id": "0d69a2b7-4a2c-4776-97bf-09da5d243e02"
		},
		"medium_text": "account@cidaas.de",
		"sub": "3e851ef6-d6f4-41c3-8ff0-8277279c0fbd",
		"status_id": "398ff79e-af29-4889-8377-f82dbf46ed63"
	}
}

认证多因素

为了认证多因素,您必须首先使用函数 initiateMFA 初始化认证过程。在初始化过程中,您将根据您选择的认证类型共享密码/验证码。允许的认证过程类型在上文已提及。

<?php
    $resp = $provider->authenticateMFA('a64782cd-d136-4fc3-a879-3afb4feb7453', '3e851ef6-d6f4-41c3-8ff0-8277279c0fbd', '123456', 'EMAIL')->wait();
?>

该函数中使用的 api 返回的响应如下。认证成功后,您可以继续进行自定义实现。对于任何失败,响应负载中的 "success" 属性将具有值 false。

{
	"success": true,
	"status": 200,
	"data": {
		"exchange_id": {
			"exchange_id": "a64782cd-d136-4fc3-a879-3afb4feb7453",
			"expires_at": "2023-11-20T07:37:01.439Z",
			"_id": "0d69a2b7-4a2c-4776-97bf-09da5d243e02",
			"createdTime": "2023-11-20T07:07:01.440Z",
			"updatedTime": "2023-11-20T07:07:01.440Z",
			"__ref": "58dfddbc8e3777f5:2a4e7a910c19bc67:58dfddbc8e3777f5:0",
			"id": "0d69a2b7-4a2c-4776-97bf-09da5d243e02"
		},
		"medium_text": "account@cidaas.de",
		"sub": "3e851ef6-d6f4-41c3-8ff0-8277279c0fbd",
		"status_id": "398ff79e-af29-4889-8377-f82dbf46ed63"
	}
}

启动账户验证

要启动账户验证,请使用函数 initiateAccountVerification。账户验证是在新创建的用户账户未经验证时进行的。如果您在 cidaas v3 上,您必须将值 v3 设置为函数参数 $version。参数 $version 是可选的。当前支持 v2 和 v3 版本。如果没有提供,则默认版本 v2 被认为进一步处理请求。函数参数 $params 的示例如下

  • verificationMedium 的允许值
    email
    sms
    ivr
  • verificationMedium 的允许值
    CODE
    LINK
<?php
    $params = [
        "response_type": "token",
        "verificationMedium": "email",
        "processingType": "code",
        "client_id": "103a3f9c-1a2d-4e47-940k-bad7f19d9604",
        "redirect_uri": "https://test.cidaas.com/user-profile/editprofile",
        "email": "account@cidaas.de"
    ]
    $provider->initiateAccountVerification($params)->wait();
?>

一旦成功启动,密码或链接将被发送到首选的验证Medium以验证您的账户

验证账户验证Medium 码

要完成账户验证,请使用函数 verifyAccount。您将需要账户验证启动过程中收到的 accvid。

<?php
    $resp = $provider->verifyAccount("103a3f9c-1a2d-4e47-940k-bad7f19d9604", "123456")->wait();
?>

该函数使用的API返回如下所示的响应。对于失败的验证,属性success的值将为false。验证成功后,您可以继续进行自定义实现。

{
    "success": true,
    "status": 200
}

执行渐进式注册

在cidaas系统中创建账户后,启动渐进式注册以处理缺失的必填注册字段。以下是渐进式注册过程中可以更新的字段。所有这些字段都需要通过函数参数 $params 传递。

IAddressEntity 和 IUserGroupMap 类型包含以下字段

IAddressEntity

IUserGroupMap

<?php
    $params = [
        "given_name": "Firstname",
        "username": "test_username",
        "family_name": "Lastname",
        "mobile_number": "7865637869"
    ]
    $resp = $provider->progressiveRegistration("103a3f9c-1a2d-4e47-940k-bad7f19d9604", "203a3f9c-1a2d-4e47-940k-bad7f19d9604", $params)->wait();
?>

获取同意详情

要获取客户端的同意详情,请使用 getConsentDetails 函数。该函数接受 3 个参数:consent_id、consent_version_id 和 sub。

<?php
    $resp = $provider->getConsentDetails("103a3f9c-1a2d-4e47-940k-bad7f19d9604", "1",  "503a3f9c-1a2d-4e47-940k-bad7f19d960")->wait();
?>

接受同意详情

要使用 sub 接受同意,请使用 acceptConsent 函数。该函数接受一个数组类型的参数。以下是需要传递到数组中的字段。以下是一个示例数组:

<?php
     $params = [
        "client_id": "1234567",
        "consent_id": "1234567",
        "consent_version_id": "1",
        "sub": "1234567",
        "url" : "https://cidaas.de/accept-consent"
    ]
    $resp = $provider->acceptConsent($params)->wait();
?>

获取MFA列表

要获取为用户配置的MFA列表,请使用 getMFAList 函数。为了获取列表,您需要首先检索一个 requestId。该函数还接受以下参数之一:

email
mobile_number
username
sub
<?php
    $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $resp = $provider->getMFAList($requestId, "account@cidaas.de")->wait();
    })
?>

启动免密码登录

要启动免密码登录,请使用 initiatePasswordlessLogin 函数。为了启动该过程,您需要首先检索一个 requestId。该函数还接受以下参数:

<?php
    $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $resp = $provider->initiatePasswordlessLogin($requestId, "email", 'account@cidaas.de', '1234567')->wait();
    })
?>

验证免密码登录

在启动过程后验证免密码登录,请使用 verifyPasswordlessLogin 函数。该函数还接受以下参数:

<?php

    $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $resp1 = $provider->initiatePasswordlessLogin($requestId, "email", 'account@cidaas.de', '1234567')->wait();
        $resp2 = $provider->verifyPasswordlessLogin("email",$resp1->exchange_id, '123456', $requestId)->wait();
    })
?>

获取用户配置文件

要获取用户配置文件,请使用 getUserProfile 函数。该函数接受以下参数:

<?php
    $resp1 = $provider->getUserProfile($accessToken, $sub)->wait();
?>

启动重置密码

要开始密码重置过程,请使用 initiateResetPassword 函数。该函数接受以下参数。该函数返回一个 resetRequestId($rprq),该 ID 用于验证发送到提供的电子邮件的代码(otp)。后来,必须提供相同的 resetRequestId 以完成密码重置过程。

<?php
   $provider->getRequestId('openid identities profile offline_access')->then(function ($requestId) {
        $res = $provider->initiateResetPassword($email, $requestId)->wait();
    })
?>

验证重置密码代码

要验证代码,请使用 handleResetPassword 函数。当密码重置过程启动时,代码将发送到用户的电子邮件。如果您在 cidaas v3 上,您必须将值 v3 设置为函数参数 version。

<?php
    $resp = $provider->handleResetPassword($code, $resetRequestId)->wait();
?>

重置密码

要完成密码重置过程,请使用 resetPassword 函数。在 cidaas 版本 v2 中,该函数返回一个包含成功 tr 或 false 的 JSON 响应。如果您在 cidaas v3 上,您必须将值 v3 设置为函数参数 version。

<?php
    $resp = $provider->resetPassword($password, $confirmPassword, $exchangeId, $resetRequestId)->wait();
?>

单元测试

有几种集成 php 单元测试的方法。除了模拟 Cidaas 类之外,您还可以为低级测试向构造函数添加一个模拟处理程序。

<?php
$cidaas = new Cidaas('https://yourcidaasinstance.cidaas.de', 'client id', 'client secret', 'https://yourwebsite/redirectAfterLogin', $mockHandler);
?>

$mockHandler 是一个默认的 guzzle 模拟实现,创建方式如下

<?php
$mock = new MockHandler([new Response(200, [], $mockedResponse)]);
$mockHandler = HandlerStack::create($this->mock);
?>

请参阅 https://docs.guzzlephp.org/en/stable/testing.html 以获取更多信息。