在构建需要安全身份验证的 Web 应用程序时,我遇到了一个常见的问题:如何集成一个既安全又用户友好的身份验证解决方案。传统的用户名/密码方式已经无法满足日益增长的安全需求,而复杂的双因素认证方案又可能降低用户体验。
这时,我发现了 smart-id,一种基于移动设备的数字身份验证解决方案。smart-id 允许用户使用他们的移动设备进行身份验证,无需记住复杂的密码或携带额外的硬件设备。然而,如何将 smart-id 集成到我的 php 应用程序中,成为了一个新的挑战。
经过一番研究,我找到了
sk-id-solutions/smart-id-php-client
这个 Composer 包,它提供了一个简洁的 PHP 接口,可以轻松地与 Smart-ID 服务进行交互。
安装
首先,你需要使用 Composer 安装该库:
<pre class="brush:php;toolbar:false;">composer require sk-id-solutions/smart-id-php-client "2.3.2"
配置客户端
立即学习“PHP免费学习笔记(深入)”;
安装完成后,你需要配置客户端的详细信息,包括 Relying Party UUID、Relying Party Name 和 Smart-ID 服务的 URL。更重要的是,为了防止中间人攻击,你需要设置 HTTPS pinning,通过指定信任的 SSL 证书的公钥哈希来确保与 Smart-ID 服务的安全连接。
<pre class="brush:php;toolbar:false;">use SKSmartIdClientClient; $this->client = new Client(); $this->client ->setRelyingPartyUUID( '00000000-0000-0000-0000-000000000000' ) // In production replace with your UUID ->setRelyingPartyName( 'DEMO' ) // In production replace with your name ->setHostUrl( 'https://sid.demo.sk.ee/smart-id-rp/v2/' ) // In production replace with production service URL // in production replace with correct server SSL key ->setPublicSslKeys("sha256//Ps1Im3KeB0Q4AlR+/J9KFd/MOznaARdwo4gURPCLaVA=");
使用语义标识符进行身份验证
接下来,你可以使用语义标识符(例如个人身份号码)来启动身份验证流程。这个过程包括生成一个随机的身份验证哈希,并将其呈现给用户,以便他们在 Smart-ID 应用程序中进行验证。
<pre class="brush:php;toolbar:false;">use SKSmartIdClientApiAuthenticationAuthenticationRequestBuilder; use SKSmartIdClientApiAuthenticationAuthenticationResponseValidator; use SKSmartIdClientApiAuthenticationNationalIdentity; use SKSmartIdClientApiAuthenticationSemanticsIdentifier; use SKSmartIdClientApiSessionStatusSessionStatusResponse; use SKSmartIdClientExceptionUserRefusedException; use SKSmartIdClientExceptionUserSelectedWrongVerificationCodeException; use SKSmartIdClientExceptionSessionTimeoutException; use SKSmartIdClientExceptionUserAccountNotFoundException; use SKSmartIdClientExceptionUserAccountException; use SKSmartIdClientExceptionEnduringSmartIdException; use SKSmartIdClientExceptionSmartIdException; use SKSmartIdClientUtilAuthenticationHash; use SKSmartIdClientApiAuthenticationCertificateLevelCode; use SKSmartIdClientApiAuthenticationInteraction; $semanticsIdentifier = SemanticsIdentifier::builder() ->withSemanticsIdentifierType('PNO') ->withCountryCode('LT') ->withIdentifier('30303039914') ->build(); // For security reasons a new hash value must be created for each new authentication request $authenticationHash = AuthenticationHash::generate(); $verificationCode = $authenticationHash->calculateVerificationCode(); // display verification code to the user echo "Verification code: " . $verificationCode . "n"; $authenticationResponse = null; try { $authenticationResponse = $this->client->authentication() ->createAuthentication() ->withSemanticsIdentifier( $semanticsIdentifier ) ->withAuthenticationHash( $authenticationHash ) ->withCertificateLevel( CertificateLevelCode::QUALIFIED ) // Certificate level can either be "QUALIFIED" or "ADVANCED" ->withAllowedInteractionsOrder((array( Interaction::ofTypeVerificationCodeChoice("Enter awesome portal?"), Interaction::ofTypeDisplayTextAndPIN("Enter awesome portal?")))) ->authenticate(); // this blocks until user has responded } catch (UserRefusedException $e) { throw new RuntimeException("You pressed cancel in Smart-ID app."); } catch (UserSelectedWrongVerificationCodeException $e) { throw new RuntimeException("You selected wrong verification code in Smart-ID app. Please try again. "); } catch (SessionTimeoutException $e) { throw new RuntimeException("Session timed out (you didn't enter PIN1 in Smart-ID app)."); } catch (UserAccountNotFoundException $e) { throw new RuntimeException("User does not have a Smart-ID account"); } catch (UserAccountException $e) { throw new RuntimeException("Unable to authenticate due to a problem with your Smart-ID account."); } catch (EnduringSmartIdException $e) { throw new RuntimeException("Problem with connecting to Smart-ID service. Please try again later."); } catch (SmartIdException $e) { throw new RuntimeException("Smart-ID authentication process failed for uncertain reason: ". $e); } // create a folder with name "trusted_certificates" and set path to that folder here: $pathToFolderWithTrustedCertificates = __DIR__ . '/../../../resources'; $authenticationResponseValidator = new AuthenticationResponseValidator($pathToFolderWithTrustedCertificates); $authenticationResult = $authenticationResponseValidator->validate( $authenticationResponse ); if ($authenticationResult->isValid()) { echo "Hooray! Authentication result is valid"; } else { throw new RuntimeException("Error! Response is not valid! Error(s): ". implode(",", $authenticationResult->getErrors())); } $authenticationIdentity = $authenticationResult->getAuthenticationIdentity(); echo "hello name: " . $authenticationIdentity->getGivenName() . ' ' . $authenticationIdentity->getSurName() . "n"; echo "from " . $authenticationIdentity->getCountry() . "n"; echo "born " . $authenticationIdentity->getDateOfBirth()->format("D d F o") . "n"; // you might need this if you want to start authentication with document number echo "Authenticated user documentNumber is: ".$authenticationResponse->getDocumentNumber(). "n";
处理异常
在身份验证过程中,可能会出现各种异常情况,例如用户取消操作、选择错误的验证码、会话超时等等。该库提供了专门的异常类来处理这些情况,你可以使用 try-catch 块来捕获这些异常并采取适当的措施。
验证身份验证结果
为了确保身份验证结果的真实性,你需要验证 Smart-ID 服务的签名。这需要你配置一个包含受信任证书的目录,并使用
AuthenticationResponseValidator
类来验证签名。
通过使用
sk-id-solutions/smart-id-php-client
库,我能够轻松地将 Smart-ID 集成到我的 PHP 应用程序中,并提供了一个安全、便捷的身份验证体验。该库的优点包括:
- 简单易用: 提供了简洁的 API,可以轻松地与 Smart-ID 服务进行交互。
- 安全性高: 支持 HTTPS pinning,可以防止中间人攻击。
- 异常处理: 提供了专门的异常类来处理各种身份验证错误。
- 结果验证: 提供了验证身份验证结果真实性的机制。
sk-id-solutions/smart-id-php-client
库极大地简化了 Smart-ID 集成过程,使我能够专注于构建应用程序的核心功能,而无需担心复杂的身份验证细节。如果你正在寻找一种安全、便捷的身份验证解决方案,那么 Smart-ID 和
sk-id-solutions/smart-id-php-client
库绝对值得考虑。
Composer在线学习地址:学习地址
以上就是告别身份验证难题:如何使用Smart-IDPHPClient实现安全便捷的身份验证的详细内容,更多请关注composer css php ai php composer try catch 标识符 接口 https ssl