bluefyn-international / aws-cognito
AWS Cognito 包,允许使用 AWS SDK for PHP 进行身份验证和其他相关功能
Requires
- php: ^7.4|^8.0
- aws/aws-sdk-php: >=3.0
- guzzlehttp/guzzle: >=6.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.17
- phpunit/phpunit: >=9.0
This package is auto-updated.
Last update: 2024-08-29 05:31:36 UTC
README
使用 AWS SDK for PHP 的 AWS Cognito 包
此包是 ellaisys/aws-cognito 的分支,但已进行重大更改,并针对 PHP 和 Laravel 的新版本。
此包提供了一种简单的方法,在 Laravel 8.x 中使用 AWS Cognito 身份验证进行 Web 和 API 身份验证驱动程序。此包的想法和一些代码基于 Pod-Point 的包,您可以在以下位置找到:[Pod-Point/laravel-cognito-auth](https://github.com/Pod-Point/laravel-cognito-auth),[black-bits/laravel-cognito-auth](https://github.com/black-bits/laravel-cognito-auth),[tymondesigns/jwt-auth](https://github.com/tymondesigns/jwt-auth)。
我们决定使用它并将它作为包贡献给社区,鼓励使用 AWS Cognito 进行标准化的身份验证,并为身份验证提供 RAD 工具。
此包包含以下功能
- 注册和确认电子邮件
- 首次登录时强制更改密码
- 登录
- 记住我cookie
- 单点登录
- 忘记密码
- 用户删除
- 编辑用户属性
- 重置用户密码
- 确认注册
- 轻松处理 API 令牌(使用缓存驱动程序)
免责声明
虽然此包在生产中使用,但它不是一个 GA(1.x)级别的发布。将会有更新/更改,可能会引起问题。此外,并非所有功能/选项都已完全实现。欢迎您就缺陷或新功能增强提出问题和 PR。然而,鉴于这是免费支持,我们无法承诺支持 SLA 或时间表。
安装
兼容性
Composer
您可以通过 composer 安装此包。
composer require bluefyn-international/aws-cognito
发布资产
您可以发布配置和视图。
php artisan vendor:publish --provider="BluefynInternational\Cognito\Providers\AwsCognitoServiceProvider"
最后但同样重要的是,您想更改身份验证驱动程序。为此,请转到您的 config\auth.php 文件,并将其更改为以下内容
'guards' => [ 'web' => [ 'driver' => 'cognito-session', // This line is important for using AWS Cognito as Web Driver 'provider' => 'users', ], 'api' => [ 'driver' => 'cognito-token', // This line is important for using AWS Cognito as API Driver 'provider' => 'users', ], ],
Cognito 用户池
为了使用 AWS Cognito 作为身份验证提供者,您需要一个 Cognito 用户池。
如果您还没有创建一个,请转到您的 [Amazon 管理控制台](https://console.aws.amazon.com/cognito/home) 并创建一个新的用户池。
接下来,生成一个应用程序客户端。这将为您提供用于 .env 文件的 App 客户端 ID 和 App 客户端密钥。
重要:别忘了激活“启用基于服务器的身份验证的登录 API”的复选框。认证流程称为:ADMIN_USER_PASSWORD_AUTH(以前称为 ADMIN_NO_SRP_AUTH)
您还需要一个具有以下访问权限的新 IAM 角色
- AmazonCognitoDeveloperAuthenticatedIdentities
- AmazonCognitoPowerUser
- AmazonESCognitoAccess
从这个用户中,您可以获取 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。
Cognito API 配置
将以下字段添加到您的 .env 文件中,并根据您的 AWS 设置设置值
# AWS configurations for cloud storage AWS_ACCESS_KEY_ID="Axxxxxxxxxxxxxxxxxxxxxxxx6" AWS_SECRET_ACCESS_KEY="mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+" # AWS Cognito configurations AWS_COGNITO_CLIENT_ID="6xxxxxxxxxxxxxxxxxxxxxxxxr" AWS_COGNITO_CLIENT_SECRET="1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1" AWS_COGNITO_USER_POOL_ID="xxxxxxxxxxxxxxxxx" AWS_COGNITO_REGION="xxxxxxxxxxx" //optional - default value is 'us-east-1' AWS_COGNITO_VERSION="latest" //optional - default value is 'latest'
有关如何找到 AWS_COGNITO_CLIENT_ID、AWS_COGNITO_CLIENT_SECRET 和 AWS_COGNITO_USER_POOL_ID 的更多详细信息,请参阅 [COGNITOCONFIG 文件](https://github.com/bluefyn-international/aws-cognito/blob/HEAD/COGNITOCONFIG.md)。
将现有用户导入 Cognito 池中
如果您已经在现有项目上工作并希望集成Cognito,您必须将用户CSV文件导入到您的Cognito池中。
用法
我们的包为您提供了5个特性,您只需将它们添加到您的认证控制器中,就可以启动我们的包。
- BluefynInternational\Cognito\Auth\AuthenticatesUsers
- BluefynInternational\Cognito\Auth\RegistersUsers
- BluefynInternational\Cognito\Auth\ResetsPasswords
- BluefynInternational\Cognito\Auth\SendsPasswordResetEmails
- BluefynInternational\Cognito\Auth\VerifiesEmails
最简单的方式是,您只需遍历您的认证控制器,将当前由Laravel实现的特性中的命名空间更改为特性。
您可以根据需要更改结构。请注意,在blade文件中的@extend语句以适应您的项目结构。当前状态下,您需要在其中定义以下4个表单字段:token
、email
、password
、password_confirmation
。
单一登录
通过我们的包和AWS Cognito,我们为您提供了一种简单的方式来实现单一登录。有关配置选项,请参阅配置文件cognito.php。
当您希望启用SSO并且用户尝试登录您的应用程序时,该包将检查用户是否存在于您的AWS Cognito池中。如果用户存在,并且add_missing_local_user_sso
设置为true
,则他将在您的数据库中自动创建,并且可以同时登录。
这就是我们使用sso_user_model
和cognito_user_fields
字段的原因。在sso_user_model
中,您定义用户模型类。在大多数情况下,这将是简单的App\User。
通过cognito_user_fields
,您可以定义应存储在Cognito中的字段。请注意,如果您定义了一个在注册请求中未发送的字段,这将抛出InvalidUserFieldException,并且您将无法注册。
现在,您已经将带有属性的用户在AWS Cognito池和您的数据库中注册,并且您想连接第二个使用相同池的应用程序。实际上,这非常简单。您可以使用允许多个项目消费相同AWS Cognito池的API配置。
*重要:如果您的用户表中有密码字段,您将不再需要它。您需要将此字段设置为可空,以便可以在没有密码的情况下创建用户。从现在开始,密码将存储在Cognito中。
您还有任何其他注册数据,例如firstname
、lastname
,需要添加到cognito.php中的cognito_user_fields配置,以便推送到Cognito。否则,它们仅在本地上存储,并且在使用单一登录时不可用。
API路由的中间件配置
如果您将此库用作API驱动程序,您可以将中间件注册到kernel.php中的$routeMiddleware。
protected $routeMiddleware = [ ... 'aws-cognito' => \BluefynInternational\Cognito\Http\Middleware\AwsCognitoAuthenticate::class ]
要使用以下标准认证中间件在Web路由中使用中间件
Route::middleware('auth')->get('user', 'NameOfTheController@functionName');
要使用以下中间件在API路由中使用中间件
Route::middleware('aws-cognito')->get('user', 'NameOfTheController@functionName');
注册用户
默认情况下,如果您使用Cognito注册新用户,Cognito将在注册过程中发送一封电子邮件,其中包含用户的用户名和临时密码,以便用户进行验证。
结合使用此库和 AWS Lambda,可以自定义电子邮件模板和内容。电子邮件模板可以是文本或HTML格式。Lambda代码不包括在此代码库中。您可以创建自己的代码。您传递给注册方法的任何对象(数组)都将原样传递给Lambda函数,我们不对属性名称做出规定。
我们使任何人都很容易使用默认行为。
- 您不需要创建额外的字段来存储验证令牌。
- 您无需担心会话或API令牌,它们将由您管理。会话或令牌通过Laravel的标准机制进行管理。您可以将其保留在任何位置,没有任何安全漏洞。
- 如果您使用我们提供的'trait BluefynInternational\Cognito\Auth\RegistersUsers',代码将仅限于几行。
- 如果您使用Laravel脚手架,则将数据库中的密码设置为可选的或在模式中删除它。密码将由AWS Cognito管理。
use BluefynInternational\Cognito\Auth\RegistersUsers; class UserController extends BaseController { use RegistersUsers; public function register(Request $request) { $validator = $request->validate([ 'name' => 'required|max:255', 'email' => 'required|email|max:64|unique:users', 'password' => 'sometimes|confirmed|min:6|max:64', ]); //Create credentials object $collection = collect($request->all()); $data = $collection->only('name', 'email', 'password'); //passing 'password' is optional. //Register User in cognito if ($cognitoRegistered=$this->createCognitoUser($data)) { //If successful, create the user in local db User::create($collection->only('name', 'email')); } //End if //Redirect to view return view('login'); } }
- 您无需关闭Cognito来发送电子邮件。我们更建议使用AWS Cognito或AWS SMS邮件,这样使用的凭据总是安全的。
用户身份验证
我们提供了一个有用的trait,使身份验证非常简单(使用Web或API路由)。您无需担心任何额外的代码来管理会话和令牌(API)。
该trait接受一些额外的参数,请参阅trait的函数签名。请注意,函数接受
此外,还传递了'guard'名称引用,因此您可以在项目中重用此函数以多个guard驱动程序。该函数具有处理多个驱动程序和提供程序的能力,这些驱动程序和提供程序在/config/auth.php中定义。
namespace BluefynInternational\Cognito\Auth; protected function attemptLogin ( Collection $request, string $guard='web', string $paramUsername='email', string $paramPassword='password', bool $isJsonResponse=false ) { ... ... ... }
如果您想为Web登录使用此trait,您可以在AuthController.php中按照以下代码编写。
namespace App\Http\Controllers; ... use BluefynInternational\Cognito\AwsCognitoClaim; use BluefynInternational\Cognito\Auth\AuthenticatesUsers as CognitoAuthenticatesUsers; class AuthController extends Controller { use CognitoAuthenticatesUsers; /** * Authenticate User * * @throws \HttpException * * @return mixed */ public function login(\Illuminate\Http\Request $request) { ... //Convert request to collection $collection = collect($request->all()); //Authenticate with Cognito Package Trait (with 'web' as the auth guard) if ($response = $this->attemptLogin($collection, 'web')) { if ($response===true) { return redirect(route('home'))->with('success', true); } else if ($response===false) { // If the login attempt was unsuccessful you may increment the number of attempts // to login and redirect the user back to the login form. Of course, when this // user surpasses their maximum number of attempts they will get locked out. // //$this->incrementLoginAttempts($request); // //$this->sendFailedLoginResponse($collection, null); } else { return $response; } //End if } //End if } //Function ends ... } //Class ends
如果您想为基于API的登录使用此trait,您可以在AuthApiController.php中按照以下代码编写。
namespace App\Api\Controller; ... use BluefynInternational\Cognito\AwsCognitoClaim; use BluefynInternational\Cognito\Auth\AuthenticatesUsers as CognitoAuthenticatesUsers; class AuthApiController extends Controller { use CognitoAuthenticatesUsers; /** * Authenticate User * * @throws \HttpException * * @return mixed */ public function login(\Illuminate\Http\Request $request) { ... //Convert request to collection $collection = collect($request->all()); //Authenticate with Cognito Package Trait (with 'api' as the auth guard) if ($claim = $this->attemptLogin($collection, 'api', 'username', 'password', true)) { if ($claim instanceof AwsCognitoClaim) { return $claim->getData(); } else { return response()->json(['status' => 'error', 'message' => $claim], 400); } //End if } //End if } //Function ends ... } //Class ends
删除用户
如果您想让您用户能够从您的应用中删除自己,您可以使用我们从CognitoClient提供的deleteUser函数。
要删除用户,应调用deleteUser函数,并将用户电子邮件作为参数传递给它。在您的cognito池中删除用户后,也请从您的数据库中删除用户。
$cognitoClient->deleteUser($user->email); $user->delete();
我们实现了一个新的配置选项delete_user
,您可以通过AWS_COGNITO_DELETE_USER
环境变量访问它。如果您将此配置设置为true,则用户将在Cognito池中删除。如果设置为false,它将保持注册状态。默认情况下,此选项设置为false。如果您想使用此行为,应设置USE_SSO为true,以便用户在成功登录后可以自行恢复。
要访问我们的CognitoClient,您只需将其作为参数传递到您想执行删除操作的控制器操作中。
public function deleteUser(Request $request, AwsCognitoClient $client)
Laravel将自动处理依赖注入。
IMPORTANT: You want to secure this action by maybe security questions, a second delete password or by confirming
the email address.
更新日志
有关最近更改的更多信息,请参阅更新日志。
安全
如果您发现任何与安全相关的问题,请将其添加到问题跟踪器。
鸣谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。