dev-object / laravel-cognito-auth
Laravel 的认证驱动程序,用于在 AWS Cognito 用户池中验证用户
Requires
- php: ^7.3|^8.0
- aws/aws-sdk-php: ^3.190
- laravel/framework: ^8.40
- nesbot/carbon: ^2.5
This package is not auto-updated.
Last update: 2024-09-24 22:06:28 UTC
README
这是一个用于 Laravel 5 的简单认证包,用于在 Amazon Cognito 用户池中验证用户。
该包与 Laravel 的原生认证系统兼容,允许验证已在 Amazon Cognito 用户池中注册的用户。它不提供用户管理功能,例如将用户注册到用户池、密码重置等。
内容
安装和设置
此包使用aws-sdk-php-laravel 包。除了设置和配置此包外,您还需要配置aws-sdk-php-laravel 以使认证工作。下面是如何操作的说明。如果您已经安装、设置和配置了aws-sdk-php-laravel,则可以跳过下面提到的部分。
安装
将 dev-object/laravel-cognito-auth
添加到 composer.json
并运行 composer update
以获取最新版本
"dev-object/laravel-cognito-auth": "~1.0"
或使用 composer require
composer require dev-object/laravel-cognito-auth
将服务提供者和 aws-sdk-php-laravel 服务提供者添加到 config/app.php
中的 providers
数组。
'providers' => [ ... Aws\Laravel\AwsServiceProvider::class, Pallant\LaravelAwsCognitoAuth\ServiceProvider::class, ... ]
打开 app/Http/Kernel.php
并将默认的 \Illuminate\Session\Middleware\AuthenticateSession::class
中间件替换为 \Pallant\LaravelAwsCognitoAuth\AuthenticateSession::class
。
protected $middlewareGroups = [ 'web' => [ ... \Pallant\LaravelAwsCognitoAuth\AuthenticateSession::class, ... ], ];
通过运行以下命令将配置文件以及 aws-sdk-php-laravel 配置文件发布到您的 config
目录:
php artisan vendor:publish --provider="Pallant\LaravelAwsCognitoAuth\ServiceProvider"
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', ], ]
打开 config/aws-cognito-auth.php
并添加您的 AWS Cognito 用户池的 ID 和用户池应用的用户池 client-id
。
'pool-id' => '<xxx-xxxxx>', ... 'apps' => [ 'default' => [ 'client-id' => '<xxxxxxxxxx>', 'refresh-token-expiration' => 30, ], ]
当为您的用户池创建应用时,默认的刷新令牌过期时间为 30 天。如果您为您的应用设置了不同的过期时间,请确保相应地更新配置文件中的 refresh-token-expiration
值。
'apps' => [ 'default' => [ 'client-id' => '<xxxxxxxxxx>', 'refresh-token-expiration' => <num-of-days>, ], ]
打开 config/aws.php
文件并将 region
值设置为您的用户池所在的区域。使用 php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"
命令创建的默认 config/aws.php
文件不包括 IAM 凭据属性,因此您需要手动添加它们。将以下内容添加到 config/aws.php
文件中,其中 key
是 IAM 用户访问密钥 ID,secret
是相应的密钥:
'credentials' => [ 'key' => <xxxxxxxxxx>, 'secret' => <xxxxxxxxxx>, ]
您的最终 config/aws.php
应该看起来像这样:
'credentials' => [ 'key' => <xxxxxxxxxx>, 'secret' => <xxxxxxxxxx>, ], 'region' => <xx-xxxx-x>, 'version' => 'latest', 'ua_append' => [ 'L5MOD/' . AwsServiceProvider::VERSION, ],
用户表
Cognito 不被视为“用户数据库”,仅用于授权用户。只有当用户已在应用程序数据库中存在时,才会向 Cognito 发出请求。这意味着您仍然需要一个填充有您想要验证的用户的 users
表。至少,此表需要 id
、email
和 remember_token
字段。
在Cognito中,每个用户都有一个用户名
。当使用Cognito进行认证时,此包将需要一个用户的属性与Cognito用户名匹配。默认情况下,它使用用户的电子邮件
属性。
如果您想使用不同的属性来存储用户的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);
如果认证失败,则将抛出\Pallant\LaravelAwsCognitoAuth\AuthAttemptException
异常,可以通过调用异常的getResponse()
方法来访问底层错误。关于AuthAttemptException。
try { Auth::attempt([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], false, AWS_COGNITO_AUTH_THROW_EXCEPTION); } catch (\Pallant\LaravelAwsCognitoAuth\AuthAttemptException $e) { $response = $e->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
时,两个方法都将返回一个\Pallant\LaravelAwsCognitoAuth\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 (\Pallant\LaravelAwsCognitoAuth\AuthAttemptException $e) { $response = $e->getResponse(); // Handle error... }); Auth::validate([ 'email' => 'xxxxx@xxxxx.xx', 'password' => 'xxxxxxxxxx', ], function (\Pallant\LaravelAwsCognitoAuth\AuthAttemptException $e) { $response = $e->getResponse(); // Handle error... };
如果认证失败,则将运行闭包,并传递一个\Pallant\LaravelAwsCognitoAuth\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()
方法,当身份验证尝试失败时将被调用。该方法将接收一个 \Pallant\LaravelAwsCognitoAuth\AuthAttemptException
实例,可以通过调用异常的 getResponse()
方法来访问底层错误。有关 AuthAttemptException 的说明。
<?php namespace App; use Pallant\LaravelAwsCognitoAuth\AuthAttemptException; class MyCustomErrorHandler { public function handle(AuthAttemptException $e) { $response = $e->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 (\Pallant\LaravelAwsCognitoAuth\AuthAttemptException $e) { $e->getResponse(); // Do something... }, ],
使用自定义类
'errors' => [ 'handler' => \App\MyCustomErrorHandler::class, ],
关于 AuthAttemptException
当使用 AWS_COGNITO_AUTH_THROW_EXCEPTION
错误处理程序时,将抛出 \Pallant\LaravelAwsCognitoAuth\AuthAttemptException
异常;或者当使用错误处理的 Clousre
方法时,将其作为参数传递。
异常的 getResponse()
方法将返回一个包含不同值的数组,这些值取决于失败尝试的原因。
在AWS Cognito API抛出异常的事件中,例如使用无效凭据时,返回的数组将包含原始异常。
[ 'exception' => CognitoIdentityProviderException {...}, ]
在 AWS Cognito API 由于某些其他原因(例如,必须通过挑战)无法进行身份验证的事件中,返回的数组将包含错误详情。
[ 'ChallengeName' => 'NEW_PASSWORD_REQUIRED', 'Session' => '...', 'ChallengeParameters' => [...], ]