phant / auth
轻松管理认证
2.1
2023-03-07 10:51 UTC
Requires
- php: >=8.1
- phant/data-structure: 4.*
Requires (Dev)
- friendsofphp/php-cs-fixer: 3.*
- phant/cache: 2.*
- phpstan/phpstan: 1.*
- phpunit/phpunit: 9.*
- psr/simple-cache: 3.*
README
演示
认证服务旨在管理应用程序和API对应用程序和用户的访问。
希望使用此服务的应用程序必须首先获取一个API密钥(需要生成)。
认证服务旨在提供一个访问令牌,允许应用程序和用户访问。
获取访问令牌的方法有多种。
访问令牌有有限的有效期。它嵌入有关其申请人的数据(应用程序、用户)。
使用的技术
PHP 8.1
Composer
用于依赖关系管理(PHP)
安装
composer install
请求访问
对于每个用例,需要以下设置。
use Phant\Auth\Domain\Service\AccessToken as ServiceAccessToken; use Phant\Auth\Domain\Service\RequestAccess as ServiceRequestAccess; use Phant\Auth\Domain\Entity\SslKey; use App\RepositoryRequestAccess; // Config $sslKey = new SslKey('private key', 'public key'); $repositoryRequestAccess = new RepositoryRequestAccess(); // Build services $serviceRequestAccess = new ServiceRequestAccess( $repositoryRequestAccess, $sslKey ); $serviceAccessToken = return new ServiceAccessToken( $sslKey, $serviceRequestAccess )
从API密钥
流程
- 应用程序通过提供其API密钥请求访问令牌,
- 服务提供访问令牌。
use Phant\Auth\Domain\Service\RequestAccessFromApiKey as ServiceRequestAccessFromApiKey; use App\RepositoryApplication; // Config $repositoryApplication = new RepositoryApplication(); // Build services $serviceRequestAccessFromApiKey = new ServiceRequestAccessFromApiKey( $serviceRequestAccess, $serviceAccessToken, $repositoryApplication ); // Obtain API key from application /* @todo */ $apiKey = 'XXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; // Request access token $accessToken = $serviceRequestAccessFromApiKey->getAccessToken($apiKey);
从Otp
流程
- 应用程序要求用户通过提供其联系信息(姓氏、名和电子邮件地址)进行认证,
- 应用程序通过提供其身份和用户的联系信息(姓氏、名和电子邮件地址)生成访问请求,
- 服务生成Otp并请求将其发送给用户,
- 用户收到Otp,
- 应用程序从用户那里检索Otp,
- 用户将收到的Otp传输给应用程序,
- 应用程序使用服务验证Otp,
- 应用程序请求访问令牌,
- 服务提供访问令牌。
Otp由您的OtpSender服务(电子邮件、短信等)发送给用户。
use Phant\Auth\Domain\Service\RequestAccessFromOtp as ServiceRequestAccessFromOtp; use Phant\Auth\Domain\Entity\Application; use Phant\Auth\Domain\Entity\User; use App\OtpSender; // Config $repositoryApplication = new RepositoryApplication(); $otpSender = new OtpSender(); // Build services $serviceRequestAccessFromOtp = new ServiceRequestAccessFromOtp( $serviceRequestAccess, $serviceAccessToken, $otpSender ); // Request access token $user = new User( 'john.doe@domain.ext', 'John', 'DOE' ); $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', 'My app', 'https://domain.ext/image.ext' ); $requestAccessToken = $serviceRequestAccessFromOtp->generate($user, $application); // Obtain Otp from user /* @todo */ $otp = '123456'; // Verify Otp $isValid = $serviceRequestAccessFromOtp->verify($otp); if ( ! $isValid) { $numberOfAttemptsRemaining = $serviceRequestAccessFromOtp->numberOfAttemptsRemaining($requestAccessToken); } // Get access token $accessToken = $serviceRequestAccessFromOtp->getAccessToken($requestAccessToken);
从第三方
流程
- 应用程序通过提供其身份生成访问请求,
- 服务生成访问请求并返回访问请求令牌,
- 应用程序通过传递访问请求令牌将认证请求转发到第三方服务,
- 用户通过第三方认证服务进行认证,
- 应用程序检索用户认证结果,
- 应用程序声明认证结果,
- 服务记录认证。
- 服务提供访问令牌。
use Phant\Auth\Domain\Service\RequestAccessFromThirdParty as ServiceRequestAccessFromThirdParty; use Phant\Auth\Domain\Entity\Application; use Phant\Auth\Domain\Entity\User; use App\RepositoryRequestAccess; // Config $repositoryApplication = new RepositoryApplication(); $otpSender = new OtpSender(); // Build services $serviceRequestAccessFromThirdParty = new ServiceRequestAccessFromThirdParty( $serviceRequestAccess, $serviceAccessToken ); // Request access token $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', 'My app', 'https://domain.ext/image.ext' ); $requestAccessToken = $serviceRequestAccessFromThirdParty->generate( $application, 'https://domain.ext/callback/url' ); // Request third party auth with requestAccessToken /* @todo */ // Obtain authentication status /* @todo */ $isAuthorized = true; // Obtain user data /* @todo */ $user = new User( 'john.doe@domain.ext', 'John', 'DOE' ); // Set auth status $serviceRequestAccessFromThirdParty->setStatus($requestAccessToken, $user, $isAuthorized); // Get access token $accessToken = $serviceRequestAccessFromThirdParty->getAccessToken($requestAccessToken);
访问令牌
访问令牌是一个JWT。
对于每个用例,需要以下设置。
use Phant\Auth\Domain\Service\AccessToken as ServiceAccessToken; use Phant\Auth\Domain\Service\RequestAccess as ServiceRequestAccess; use Phant\Auth\FixtDomainure\DataStructure\SslKey; use App\RepositoryRequestAccess; // Config $sslKey = new SslKey('private key', 'public key'); $repositoryRequestAccess = new RepositoryRequestAccess(); // Build services $serviceRequestAccess = new ServiceRequestAccess( $repositoryRequestAccess, $sslKey ); $serviceAccessToken = return new ServiceAccessToken( $sslKey, $serviceRequestAccess ) // An access token $accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhcHAiOnsiaWQiOiJjMjI4MDI1OC03OGU5LTQ4ZmQtOTA1Zi0yYzhlMDIzYWNiOWMiLCJuYW1lIjoiRmxhc2hwb2ludCIsImxvZ28iOiJodHRwczpcL1wvdmlhLnBsYWNlaG9sZGVyLmNvbVwvNDAweDIwMD90ZXh0PUZsYXNocG9pbnQiLCJhcGlfa2V5IjoiZnc5TEFJcFkuclA2b2d5VlNRdEx1OWRWMXBqOTR2WG56ekVPNXNISldHeHdhNWMxZzZMa3owNlo5dGNuc21GNFNieVRqeURTaCJ9LCJ1c2VyIjp7ImVtYWlsX2FkZHJlc3MiOiJqb2huLmRvZUBkb21haW4uZXh0IiwibGFzdG5hbWUiOiJET0UiLCJmaXJzdG5hbWUiOiJKb2huIiwicm9sZSI6bnVsbH0sImlhdCI6MTY2MzY4NDM3MCwiZXhwIjoxNjYzNjk1MTcwfQ.a-wJ_T1ENG58zCw2X7oP2oZrziZRP_m0rOOkUkC2axAsx7O72ebGjQja-iry-lFvd1PF48BxejQw69LPUQKrx1Tb9oQ_8VqMhU97nR8Jd5v2jlWIA7CP2H9voQLE5ybHpqFO2IzgPf2MurzwXQ0tlSeiRbQzHLzMBbWhcQLU4aI';
JWT解密方法
应用程序可能需要以下用途的公钥
- 检查令牌的完整性,
- 从令牌中提取数据。
use Phant\DataStructure\Token\Jwt; use Phant\Error\NotCompliant; $publicKey = $serviceAccessToken->getPublicKey(); try { $payLoad = (new Jwt($accessToken))->decode($publicKey); } catch (NotCompliant $e) { }
验证
应用程序可以使用服务验证令牌的完整性。
use Phant\Auth\Domain\Entity\Application; $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', 'My app', 'https://domain.ext/image.ext' ); $isValid = $serviceAccessToken->check($accessToken, $application);
获取有效载荷
应用程序可以从服务中获取令牌有效载荷。
use Phant\Auth\Domain\Entity\Application; $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', 'My app', 'https://domain.ext/image.ext' ); $payload = $serviceAccessToken->getPayload($accessToken);