zarate-systems / laravel-cognito-auth
为Laravel提供了一种认证驱动,用于在AWS Cognito用户池中认证用户。
Requires
- php: ^8.0
- ext-json: *
- aws/aws-sdk-php-laravel: ^3.7
- illuminate/auth: ^9.0
- illuminate/http: ^9.0
- illuminate/support: ^9.0
This package is auto-updated.
Last update: 2024-09-09 12:40:50 UTC
README
此包是从 ArranJacques/laravel-aws-cognito-auth 分支出来的,但已更新到Laravel 8。
这是一个简单的认证包,适用于Laravel 8和9,用于在Amazon Cognito用户池中认证用户。
此包与Laravel的本地认证系统兼容,允许认证已在Amazon Cognito用户池中注册的用户。它不提供用户管理功能,例如将用户注册到用户池、密码重置等。
安装
此包使用了aws-sdk-php-laravel包。除了设置和配置此包外,您还需要配置aws-sdk-php-laravel以使认证工作。下面是如何操作的说明。如果您已经安装、设置和配置了aws-sdk-php-laravel,则可以跳过以下提到的部分。
您可以通过composer安装此包
composer require zarate-systems/laravel-cognito-auth
配置
打开app/Http/Kernel.php
文件,将默认的\Illuminate\Session\Middleware\AuthenticateSession::class
中间件替换为\ZarateSystems\LaravelCognitoAuth\AuthenticateSession::class
protected $middlewareGroups = [ 'web' => [ ... \ZarateSystems\LaravelCognitoAuth\AuthenticateSession::class, ... ], ];
通过运行以下命令将配置文件以及aws-sdk-php-laravel配置文件发布到您的配置目录:
php artisan vendor:publish --provider="ZarateSystems\LaravelCognitoAuth\LaravelCognitoAuthServiceProvider"
php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"
打开config/auth.php
文件,并将默认保护器的驱动程序设置为aws-cognito
。默认情况下,默认保护器是web
,因此您的config/auth.php
看起来可能如下所示:
'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ],
更改驱动程序。
'guards' => [ 'web' => [ 'driver' => 'aws-cognito', 'provider' => 'users', ], ],
将以下环境变量添加到.env
文件中。
AWS_COGNITO_IDENTITY_POOL_ID=YOUR_POOL_ID AWS_COGNITO_IDENTITY_APP_CLIENT_ID=YOUR_CLIENT_ID
- 注意
当为用户池创建应用程序时,默认的刷新令牌过期时间为30天。如果您为应用程序设置了不同的过期时间,请确保您已更新
config/aws-cognito-auth.php
文件中的refresh-token-expiration
值。
'apps' => [ 'default' => [ 'client-id' => env('AWS_COGNITO_IDENTITY_APP_CLIENT_ID', ''), 'refresh-token-expiration' => <num-of-days>, ], ],
打开config/aws.php
文件,并将region
值设置为您的用户池所在的区域。使用php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"
命令创建的默认config/aws.php
文件不包含IAM凭证属性,因此您需要手动添加它们。
将以下内容添加到.env
文件中。
AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY AWS_REGION=YOUR_DEFAULT_REGION
其中AWS_ACCESS_KEY_ID
是IAM用户访问密钥ID,AWS_SECRET_ACCESS_KEY
是相应的密钥。
用户表
Cognito不视为“用户数据库”,仅用于授权用户。除非用户已存在于应用程序的数据库中,否则不会向Cognito发出请求。这意味着您仍然需要一个包含您想要认证的用户的信息的用户表。至少,此表需要包含id
、email
和remember_token
字段。
在Cognito中,每个用户都有一个username
。当通过Cognito进行认证时,此包需要匹配用户的一个属性以与用户的Cognito用户名相匹配。默认情况下,它使用用户的email
属性。
如果您想使用不同的属性来存储用户的Cognito用户名,可以通过首先在您的users
表中添加一个新的字段,例如cognito_username,然后在config/aws-cognito-auth.php
文件中将username-attribute
设置为该字段的名称来实现。
使用方法
安装和配置完成后,身份验证将像Laravel原生身份验证一样工作。有关详细信息,请参阅Laravel的文档。
身份验证
身份验证
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ]);
身份验证并记住
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], true);
获取已验证的用户
Auth::user();
注销
Auth::logout();
除了默认功能外,还有一些额外的方法可用于访问用户的Cognito访问令牌、id令牌等。
Auth::getCognitoAccessToken();
Auth::getCognitoIdToken();
Auth::getCognitoRefreshToken();
Auth::getCognitoTokensExpiryTime();
Auth::getCognitoRefreshTokenExpiryTime();
处理失败的身份验证
AWS Cognito可能由于多种原因而无法进行身份验证,从简单地输入错误的凭据,到需要额外的检查或操作才能成功进行身份验证。
为了您能够适当处理失败尝试,该包中提供了一些选项,用于指定如何处理失败尝试。
方法
您可以通过在调用Auth::attempt()
和Auth::validate()
方法时传递额外的$errorHandler
参数来指定如何处理失败尝试。
Auth::attempt(array $credentials, [bool $remember], [$errorHandler]); Auth::validate(array $credentials, [$errorHandler]);
无错误处理
如果没有传递$errorHandler
,则所有失败的身份验证尝试都将被内部处理和抑制,并且Auth::attempt()
和Auth::validate()
方法将简单地返回true或false,以指示身份验证尝试是否成功。
抛出异常
要使Auth::attempt()
和Auth::validate()
方法抛出异常,请将AWS_COGNITO_AUTH_THROW_EXCEPTION
作为$errorHandler
参数传递。
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, AWS_COGNITO_AUTH_THROW_EXCEPTION); Auth::validate([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], AWS_COGNITO_AUTH_THROW_EXCEPTION);
如果身份验证失败,则将抛出\ZarateSystems\LaravelCognitoAuth\AuthAttemptException
异常,可以通过调用异常的getResponse()
方法来访问底层错误。关于AuthAttemptException。
try { Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, AWS_COGNITO_AUTH_THROW_EXCEPTION); } catch (\ZarateSystems\LaravelCognitoAuth\AuthAttemptException $exception) { $response = $exception->getResponse(); // Handle error... }
返回尝试实例
要使Auth::attempt()
和Auth::validate()
方法返回一个尝试对象,请将AWS_COGNITO_AUTH_RETURN_ATTEMPT
作为$errorHandler
参数传递。
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, AWS_COGNITO_AUTH_RETURN_ATTEMPT); Auth::validate([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], AWS_COGNITO_AUTH_RETURN_ATTEMPT);
当使用AWS_COGNITO_AUTH_RETURN_ATTEMPT
时,两个方法都将返回一个\ZarateSystems\LaravelCognitoAuth\AuthAttempt
实例,可以用来检查身份验证尝试是否成功。
$attempt = Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, AWS_COGNITO_AUTH_RETURN_ATTEMPT); if ($attempt->successful()) { // Do something... } else { $response = $attempt->getResponse(); // Handle error... }
对于不成功的身份验证尝试,可以使用尝试实例的getResponse()
方法来访问底层错误。此方法将返回一个包含不同值的数据数组,具体取决于失败尝试的原因。
在AWS Cognito API抛出异常的事件中,例如使用无效凭据时,返回的数组将包含原始异常。
[ 'exception' => CognitoIdentityProviderException {...}, ]
在AWS Cognito API由于其他原因无法进行身份验证的事件中,例如需要通过挑战时,返回的数组将包含错误详情。
[ 'ChallengeName' => 'NEW_PASSWORD_REQUIRED', 'Session' => '...', 'ChallengeParameters' => [...], ]
使用闭包
要使用闭包处理失败的身份验证尝试,请将其作为Auth::attempt()
和Auth::validate()
方法的$errorHandler
参数传递。
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, function (\ZarateSystems\LaravelCognitoAuth\AuthAttemptException $exception) { $response = $exception->getResponse(); // Handle error... }); Auth::validate([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], function (\ZarateSystems\LaravelCognitoAuth\AuthAttemptException $exception) { $response = $exception->getResponse(); // Handle error... };
如果身份验证失败,则将运行闭包,并将传递一个\ZarateSystems\LaravelCognitoAuth\AuthAttemptException
实例,可以用来通过调用异常的getResponse()
方法来访问底层错误。关于AuthAttemptException。
使用自定义类
要使用自定义类处理失败的身份验证尝试,请将其名称作为Auth::attempt()
和Auth::validate()
方法的$errorHandler
参数传递。
Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, \App\MyCustomErrorHandler::class); Auth::validate([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], \App\MyCustomErrorHandler::class);
错误处理器类应该有一个 handle()
方法,当身份验证尝试失败时将被调用。该 handle()
方法将传递一个 \ZarateSystems\LaravelCognitoAuth\AuthAttemptException
实例,可以通过调用异常的 getResponse()
方法来访问底层错误。关于 AuthAttemptException。
<?php namespace App; use ZarateSystems\LaravelCognitoAuth\AuthAttemptException; class MyCustomErrorHandler { public function handle(AuthAttemptException $exception) { $response = $exception->getResponse(); // Handle error... } }
默认错误处理器
除了在线定义错误处理器,还可以在 config/aws-cognito-auth.php
文件中定义默认错误处理器。上面详细介绍了相同的错误处理方法。当使用 AWS_COGNITO_AUTH_THROW_EXCEPTION
或 AWS_COGNITO_AUTH_RETURN_ATTEMPT
设置值时,将其作为字符串,不要使用常量。
抛出异常
'errors' => [ 'handler' => 'AWS_COGNITO_AUTH_THROW_EXCEPTION', ],
返回尝试
'errors' => [ 'handler' => 'AWS_COGNITO_AUTH_RETURN_ATTEMPT', ],
使用闭包
'errors' => [ 'handler' => function (\ZarateSystems\LaravelCognitoAuth\AuthAttemptException $exception) { $exception->getResponse(); // Do something... }, ],
使用自定义类
'errors' => [ 'handler' => \App\MyCustomErrorHandler::class, ],
关于 AuthAttemptException
使用 AWS_COGNITO_AUTH_THROW_EXCEPTION
错误处理器时,将抛出 \ZarateSystems\LaravelCognitoAuth\AuthAttemptException
异常,或在错误处理的 Clousre
方法中使用时作为参数传递。
异常的 getResponse()
方法将返回一个数组,其中包含根据失败尝试的原因而不同的值。
在AWS Cognito API抛出异常的事件中,例如使用无效凭据时,返回的数组将包含原始异常。
[ 'exception' => CognitoIdentityProviderException {...}, ]
在 AWS Cognito API 由于某些其他原因(例如,必须传递一个挑战)而未能进行身份验证的事件中,返回的数组将包含错误详情。
[ 'ChallengeName' => 'NEW_PASSWORD_REQUIRED', 'Session' => '...', 'ChallengeParameters' => [...], ]
更新日志
请参阅 CHANGELOG 以获取有关最近更改的更多信息。
贡献
请参阅 CONTRIBUTING 以获取详细信息。
安全
如果您发现任何安全问题,请通过电子邮件 zaraterick@outlook.com 而不是使用问题跟踪器。
致谢
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 以获取更多信息。
Laravel 包模板
此包是使用 Laravel 包模板 生成的。