zarate-systems/laravel-cognito-auth

为Laravel提供了一种认证驱动,用于在AWS Cognito用户池中认证用户。

v2.0.0 2022-03-09 06:34 UTC

This package is auto-updated.

Last update: 2024-09-09 12:40:50 UTC


README

Banner Total Downloads StyleCI

此包是从 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发出请求。这意味着您仍然需要一个包含您想要认证的用户的信息的用户表。至少,此表需要包含idemailremember_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_EXCEPTIONAWS_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 包模板 生成的。