hchoilabs/laravel-cognito-auth

为 Laravel 提供的 AWS Cognito 认证服务提供商。

dev-master 2023-08-11 20:30 UTC

This package is auto-updated.

Last update: 2024-09-11 22:38:23 UTC


README

Latest Version on Packagist Total Downloads StyleCI

本软件包提供了一种简单的方式来在 Laravel 中使用 AWS Cognito 认证。本软件包的理念和一些代码基于 Pod-Point 的软件包,您可以在以下位置找到它: 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 和 App 客户端密钥。

重要:不要忘记勾选复选框以启用基于服务器的认证的登录 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

以最简单的方式,您只需遍历您的 Auth 控制器,并将当前已实现的特质从 Laravel 的命名空间更改为我们的特质。

在发布我们的软件包的过程中,您创建了一个视图,您可以在 Resources/views/vendor/black-bits/laravel-cognito-auth 下找到它。

您可以根据需求调整结构。请注意blade文件中的@extend语句,以适应您的项目结构。当前状态下,您需要在此处定义这4个表单字段:tokenemailpasswordpassword_confirmation

单点登录

使用我们的包和AWS Cognito,我们为您提供了一种简单的方式来使用单点登录。有关配置选项,请查看config cognito.php

要启用单点登录,您可以在.env文件中将USE_SSO设置为true。

USE_SSO=true

当您在配置中启用SSO且用户尝试登录您的应用程序时,我们将检查用户是否存在于您的Cognito池中。如果用户存在,他将被自动创建在您的数据库中,并同步登录。

这就是我们使用sso_user_modelsso_user_fields字段的原因。在sso_user_model中,您定义用户模型的类。在大多数情况下,这将仅仅是App\User

使用sso_user_fields,您可以定义应该存储在Cognito中的字段。请注意这里。如果您定义了一个不随注册请求一起发送的字段,这将引发InvalidUserFieldException,并且您将无法注册。

现在您已经使用属性在Cognito池和数据库中注册了用户,并且想要连接第二个应使用相同池的应用。实际上,这相当简单。按照您习惯的方式设置项目,并安装laravel-cognito-auth包。在两个地方都将use_sso设置为true。确保您输入了完全相同的池ID。现在,当用户在您的其他应用程序中注册但不在第二个应用程序中注册并想要登录时,他将会被创建。这就是您需要做的全部。

重要:如果您的用户表中有密码字段,您将不再需要它。您想要做的是将此字段设置为可空,以便可以在没有密码的情况下创建用户。从现在起,密码将存储在Cognito中。您有任何其他注册数据,例如firstnamelastname,需要添加到cognito.php中的sso_user_fields配置中,以便推送到Cognito。否则,它们只会在本地存储,且在您想要使用单点登录时不可用。

注册用户

默认情况下,如果您使用Cognito注册新用户,Cognito将在注册期间发送一封电子邮件,用户可以通过该电子邮件进行验证。如果用户现在点击电子邮件中的链接,他将重定向到由Cognito提供的确认页面。在大多数情况下,这并不是您想要的。您希望用户留在您的页面上。

我们发现了一种绕过此默认行为的好方法。

  1. 您需要为用户创建一个额外的字段,用于存储验证令牌。此字段必须是可空的。

  2. 创建一个事件监听器,该监听器监听注册事件,该事件在用户注册后触发。

  3. 在此事件监听器中,您生成令牌并将其存储在您创建的上面的字段中。

  4. 您创建一封电子邮件并将存储在该链接中的令牌发送给用户。

  5. 该链接应指向一个控制器操作,您首先检查是否存在具有此令牌的用户。如果数据库中存在这样的用户,您将调用Cognito并将用户的Attributes设置为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');
        }
    
  6. 现在您需要关闭Cognito以发送电子邮件。进入您的AWS账户,导航到Cognito部分。选择您的用户池,点击MFA和验证。您将看到一个标题:您想要要求验证电子邮件或电话号码吗?您必须在这里取消所有选中的字段。完成后,您应该会看到一个红色警告:您尚未选择电子邮件或电话号码验证,因此您的用户将无法在不联系您寻求支持的情况下恢复他们的密码。

  7. 现在您已经告诉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)。有关更多信息,请参阅许可文件