black-bits / laravel-cognito-auth
用于Laravel的AWS Cognito身份验证提供商。
Requires
- php: ^7.1|^8.0
- aws/aws-sdk-php: ^3.61
- illuminate/auth: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|^9.0
- illuminate/config: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|^9.0
- illuminate/http: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|^9.0
- illuminate/support: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.*|7.*|8.*|^9.0
Requires (Dev)
- larapack/dd: ^1.0
- phpunit/phpunit: ^7.0|^9.5.10
README
本包提供了一种简单的方式在Laravel中使用AWS Cognito身份验证。本包的构思和一些代码基于Pod-Point提供的包,您可以在以下地址找到:[Pod-Point/laravel-cognito-auth](https://github.com/Pod-Point/laravel-cognito-auth)。我们决定以它为基础创建自己的包,因为我们希望在某些方面进行定制以适应我们的需求。
目前我们已经在包中实现了以下功能
- 注册和确认邮件
- 登录
- 记住我Cookie
- 单点登录
- 忘记密码
- 用户删除
- 编辑用户属性
- 重置用户密码
- 确认注册
免责声明
本包目前处于开发阶段,尚未准备就绪用于生产。
安装
您可以通过composer安装此包。
composer require black-bits/laravel-cognito-auth
Laravel 5.4及之前版本
在使用Laravel 5.5之前的版本时,您需要手动注册服务提供商。
// config/app.php 'providers' => [ ... BlackBits\LaravelCognitoAuth\CognitoAuthServiceProvider::class, ];
接下来,您可以发布配置和视图。
php artisan vendor:publish --provider="BlackBits\LaravelCognitoAuth\CognitoAuthServiceProvider"
最后,您需要更改身份验证驱动程序。要这样做,请访问您的config\auth.php文件,并将其更改为以下内容:
'guards' => [
'web' => [
'driver' => 'cognito', // This line is important
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
Cognito用户池
为了使用AWS Cognito作为身份验证提供商,您需要一个Cognito用户池。
如果您还没有创建一个,请访问您的Amazon管理控制台并创建一个新的用户池。
接下来,生成一个应用客户端。这将为您提供用于.env文件的App客户端ID和应用客户端密钥。
重要:不要忘记勾选启用“服务器端身份验证的登录API”的复选框。身份验证流程称为:ADMIN_USER_PASSWORD_AUTH(以前称为ADMIN_NO_SRP_AUTH)。
您还需要一个新的IAM角色,具有以下访问权限:
- AmazonCognitoDeveloperAuthenticatedIdentities
- AmazonCognitoPowerUser
- AmazonESCognitoAccess
从这个用户中,您可以获取AWS_COGNITO_KEY和AWS_COGNITO_SECRET。
Cognito API配置
将以下字段添加到您的.env文件中,并根据您的AWS设置设置值
AWS_COGNITO_KEY=
AWS_COGNITO_SECRET=
AWS_COGNITO_REGION=
AWS_COGNITO_CLIENT_ID=
AWS_COGNITO_CLIENT_SECRET=
AWS_COGNITO_USER_POOL_ID=
AWS_COGNITO_DELETE_USER=
将现有用户导入Cognito池
如果您正在处理一个现有的项目并且想要集成Cognito,您需要将用户CSV文件导入到您的Cognito池中。
使用方法
我们的包为您提供了5个特质,您可以将其添加到您的Auth控制器中,以使包运行。
- BlackBits\LaravelCognitoAuth\Auth\AuthenticatesUsers
- BlackBits\LaravelCognitoAuth\Auth\RegistersUsers
- BlackBits\LaravelCognitoAuth\Auth\ResetsPasswords
- BlackBits\LaravelCognitoAuth\Auth\SendsPasswordResetEmails
- BlackBits\LaravelCognitoAuth\Auth\VerifiesEmails
在 simplest way,您只需遍历您的Auth控制器,将当前从Laravel实现的特质中的命名空间更改即可。
在发布我们的包的过程中,您创建了一个视图,您可以在Resources/views/vendor/black-bits/laravel-cognito-auth
下找到它。
您可以更改结构以适应您的需求。请注意blade文件中的@extend语句,以适应您的项目结构。在当前状态下,您需要在这里定义这4个表单字段:token、email、password和password_confirmation。
单点登录
通过我们的包和AWS Cognito,我们为您提供了一种简单的方式来使用单点登录。有关配置选项,请参阅config中的cognito.php文件。cognito.php。
要启用单点登录,您可以在.env文件中将USE_SSO设置为true。
USE_SSO=true
当您在配置中启用了SSO并且用户尝试登录到您的应用程序时,我们将检查用户是否存在于您的Cognito池中。如果用户存在,他将被自动创建在您的数据库中,并同时登录。
这就是我们使用sso_user_model
和sso_user_fields
字段的原因。在sso_user_model
中,您定义用户模型类。在大多数情况下,这将是简单的App\User。
使用sso_user_fields
,您可以定义应存储在Cognito中的字段。请注意。如果您定义了一个在注册请求中未发送的字段,这将抛出InvalidUserFieldException,您将无法注册。
现在您已经将具有Cognito池和数据库中用户属性的用户注册好了,并且您想附加一个应使用相同池的第二个应用程序。实际上,这相当简单。按照您习惯的方式设置项目,并安装我们的laravel-cognito-auth包。在两个网站上设置use_sso
为true。确保您输入了完全相同的池ID。现在,当用户在您的其他应用程序中注册但未在第二个应用程序中注册,并想要登录时,他将创建。这就是您需要做的全部。
重要提示:如果您的用户表有一个密码字段,您将不再需要它。您想做的就是把此字段设置为可空的,这样就可以在不输入密码的情况下创建用户。从现在起,密码存储在Cognito中。您有的任何其他注册数据,例如firstname
、lastname
,需要添加到cognito.php中的sso_user_fields配置,以推送到Cognito。否则,它们仅本地存储,且在您想使用单点登录时不可用。
注册用户
默认情况下,如果您使用Cognito注册新用户,Cognito将在signUp期间发送一封电子邮件,用户可以在其中验证自己。如果用户现在点击电子邮件中的链接,他将被重定向到Cognito提供的确认页面。在大多数情况下,这不是您想要的。您希望用户留在您的页面上。
我们找到了一种巧妙的方法来绕过这种默认行为。
-
您需要为用户创建一个额外的字段,用于存储验证令牌。此字段必须为可空的。
-
创建一个事件监听器,监听注册事件,该事件在用户注册后触发。
-
在此事件监听器中,您生成一个令牌并将其存储在上面的字段中。
-
您创建一封电子邮件并将存储在链接中的令牌发送给用户。
-
链接应指向一个控制器操作,首先检查是否存在具有此令牌的用户。如果数据库中存在此类用户,则调用Cognito并将用户属性email_verified设置为true,并确认注册。
public function verifyEmail( $token, CognitoClient $cognitoClient, CognitoUserPropertyAccessor $cognitoUserPropertyAccessor ) { $user = User::whereToken($token)->firstOrFail(); $user->token = null; $user->save(); $cognitoClient->setUserAttributes($user->email, [ 'email_verified' => 'true', ]); if ($cognitoUserPropertyAccessor->getUserStatus($user->email) != 'CONFIRMED') { $cognitoClient->confirmSignUp($user->email); return response()->redirectToRoute('login'); } return response()->redirectToRoute('dashboard'); }
-
现在您需要关闭Cognito以发送邮件。进入您的AWS账户,并导航到Cognito部分。选择您的用户池,然后点击
MFA和验证
。您将看到一个标题:您想要求验证电子邮件或电话号码吗?
您必须在这里取消所有勾选的选项。完成操作后,您应该看到一个红色警报:您未选择电子邮件或电话号码验证,因此您的用户将无法在没有联系您支持的情况下恢复密码。
-
现在您已经告诉Cognito在用户在您的应用程序上注册时停止向您发送消息,您可以自己处理所有这些。
顺便说一句:忘记密码的电子邮件仍然将通过Cognito触发。您无法将其关闭,因此请确保调整这些电子邮件以适应您的需求。同时,请确保从适当的FROM地址发送电子邮件。
删除用户
如果您想允许您的用户从您的应用程序中删除自己,您可以使用我们的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, CognitoClient $cognitoClient)
Laravel将自行处理依赖注入。
IMPORTANT: You want to secure this action by maybe security questions, a second delete password or by confirming
the email address.
变更日志
有关最近更改的更多信息,请参阅变更日志。
安全性
如果您发现任何与安全相关的问题,请通过电子邮件hello@blackbits.io联系,而不是使用问题跟踪器。
鸣谢
支持我们
Black Bits, Inc.是一家位于俄勒冈州格兰茨帕斯的专业从事Laravel和AWS的网页和咨询公司。您可以在我们的网站上找到我们工作的概述在这里。
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。