Cruddur Google IDP与AWS Cognito集成(无托管UI)
#aws #react #python #cognito

本文基于Andrew Brown's AWS Cloud Project bootcamp中使用的CRUDDUR应用程序。

我已经实施了可能不是完美的解决方案,但它符合其目的。如果您有任何建议或遇到任何问题,请随时让我知道。

设置Google Auth提供商

参考:Setup your auth provider

select-project

  • 单击新项目
  • 输入您的项目的名称,然后单击创建
  • 创建项目后,从左侧的“导航”菜单中选择 apis&emervice
  • 接下来,单击凭据

api-creds

  • 单击配置屏幕的同意
  • 接下来,单击创建

click-create

  • 输入应用程序信息的所需信息开发人员联系信息字段,然后单击保存并继续 3次(OAuth同意屏幕 - >范围 - >测试用户)要完成同意屏幕设置。
  • 在左侧导航菜单中,单击凭据 tab。
  • 要创建您的OAuth 2.0凭据,请从创建凭据下拉列表中选择 oauth client ID

oauth-creds

  • 选择 Web Application 作为应用程序类型并将其命名为OAuth客户端。
  • 单击创建
  • 记下您的客户ID 和您的客户秘密。您将需要下一节。
  • 选择 ok

在您的用户池中添加社交IDP

参考:Adding social identity providers to a user pool

  • 转到Amazon Cognito console并选择用户池
  • 从列表中选择 cruddur-user-pool 用户池。
  • 单击登录体验选项卡,然后找到联合登录。单击添加身份提供商
  • 选择 Google 作为您的社交IDP。
  • 输入Google Developer Console App Client ID App客户端秘密是在上一节中生成的。
  • 对于授权范围,添加以下内容:
profile email openid
  • 从您的IDP到用户池的地图属性。

Map attributes

用户池属性 Google属性
电子邮件 电子邮件
名称 名称
preferred_username given_name
用户名 sub
  • 选择添加身份提供者。
  • app client Integration tab中,从列表中选择 app client ',单击 编辑托管托管UI设置

Hosted UI

  • 目前,为添加一个url http://localhost:3000允许的回调URLS 允许登录URL â(可选)。
  • selectâ google 身份提供商菜单。
  • 确保设置 oauth 2.0授予类型 n emnit grant 。这说明客户端应直接接收访问令牌(并且可以选择地,基于范围的ID令牌)。

Implicit auth

有一个建议使用授权代码的选项,但是为了这样做,我们需要在后端中实现代码Exchange(PKCE)的证明密钥,这会使事物复杂化。因此,目前,请坚持将令牌直接发送给客户的选项(隐式赠款)。

  • openID连接范围菜单中,选择 openID - 然后是 .cognito.sign.user.user.admin email email /em>,以及 profile
  • 选择“ ”保存更改

请注意,我们需要选择 aws.cognito.signin.user.admin 该范围用于允许用户从所有设备中登录其会话。有关更多信息,请参见this Stack Overflow post

尽管我们已经启用了托管UI,但我们不会在项目中使用它。需要启用托管的UI,以使社交IDP登录工作。有关更多信息,请参见Adding social identity providers to a user pool

将发现域添加到Google Developer Console

  • 转到Google developer console
  • 在左导航栏上,选择凭据。
  • 选择您在第一步中创建的客户端,然后单击“编辑”按钮。

add-domain-oauth

  • 授权的JavaScript Origins 字段中,输入您的用户池域。
  • 授权重定向uris 字段中,使用/oauth2/idpresponse端点输入您的用户池域。

add-url-google

  • 单击保存保存更改。

注意:如果您看到一条错误消息,该消息说“无效重定向:必须在提交端点之前添加到授权域列表中”,请添加端点时,请转到授权的域列表并添加域。更多信息:Social sign-in (OAuth)

测试您的社交IDP配置

  • 返回到 cruddur-user-pool 控制台,从动作下拉列表下的域菜单中,选择创建cognito域。

Create Domain

  • 输入独特的域前缀。

Unique Domain

要查看托管的UI,请使用您的凭据更新下面给出的URL,然后使用它访问托管的UI身份验证页面:

  • 用刚创建的域URL替换<your_user_pool_domain>
  • 用用户池应用的客户端ID替换<your_client_id>
https://<your_user_pool_domain>/login?response_type=token&client_id=<your_client_id>&redirect_uri=http://localhost:3000

这是您访问此URL时将显示的页面。

Hosted UI Google Button

尝试使用此按钮签名。如果遇到任何错误,请确保正确遵循所有前面的步骤。

成功注册后,您将被重定向到 localhost:3000 ,并且由于端口3000上没有任何运行。不用担心;我们稍后将解决此问题。

更新App.js

  • 在前端服务下,将此环境变量添加到docker-compose.yml文件:
REACT_APP_FRONTEND_URL: "https://3000-${GITPOD_WORKSPACE_ID}.${GITPOD_WORKSPACE_CLUSTER_HOST}"
  • 使用以下更改更新frontend-react-js/src/App.js文件:
Amplify.configure({
  AWS_PROJECT_REGION: process.env.REACT_APP_AWS_PROJECT_REGION,
  aws_cognito_region: process.env.REACT_APP_AWS_COGNITO_REGION,
  aws_user_pools_id: process.env.REACT_APP_AWS_USER_POOLS_ID,
  aws_user_pools_web_client_id: process.env.REACT_APP_CLIENT_ID,
  oauth: {
    domain: '<your_user_pool_domain_without_http>',
    scope: ['email', 'profile', 'openid', "aws.cognito.signin.user.admin"],
    redirectSignIn: process.env.REACT_APP_FRONTEND_URL,
    redirectSignOut: process.env.REACT_APP_FRONTEND_URL,
    responseType: 'token' // or 'token', note that REFRESH token will only be generated when the responseType is code
  },

  Auth: {
    // We are not using an Identity Pool
    // identityPoolId: process.env.REACT_APP_IDENTITY_POOL_ID, // REQUIRED - Amazon Cognito Identity Pool ID
    region: process.env.REACT_APP_AWS_PROJECT_REGION, // REQUIRED - Amazon Cognito Region
    userPoolId: process.env.REACT_APP_AWS_USER_POOLS_ID, // OPTIONAL - Amazon Cognito User Pool ID
    userPoolWebClientId: process.env.REACT_APP_CLIENT_ID, // OPTIONAL - Amazon Cognito Web Client ID (26-char alphanumeric string)
  },
});

â!注意:确保用户池域没有HTTPS前缀。

自动将重定向URL设置在cognito中

AWS CLI文档:https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/update-user-pool-client.html

  • 请记住我们添加Localhost的步骤:3000到允许的回调URL 允许的登录URL-可选
  • 我们需要Cognito托管UI设置中的重定向URL与我们的前端URL相同。为了实现这一目标,请在frontend-react-js中创建一个/bin文件夹。
  • bin文件夹中,创建一个称为auto-redirect的bash脚本,每当我们在GitPod中打开工作区时,都会自动更新URL。添加此命令:
#! /usr/bin/bash

aws cognito-idp update-user-pool-client \
--user-pool-id $AWS_USER_POOLS_ID \
--client-id $CLIENT_ID \
--callback-urls https://3000-$GITPOD_WORKSPACE_ID.$GITPOD_WORKSPACE_CLUSTER_HOST \
--logout-urls https://3000-$GITPOD_WORKSPACE_ID.$GITPOD_WORKSPACE_CLUSTER_HOST \
--supported-identity-providers Google \
--allowed-o-auth-flows-user-pool-client \
--allowed-o-auth-flows implicit \
--allowed-o-auth-scopes {email,openid,profile,aws.cognito.signin.user.admin}
  • 确保通过从根文件夹运行chmod u+x ./frontend-react-js/bin/auto-redirect使脚本可执行。
  • 从终端运行此命令并验证是否获得有效的响应,并且是否在 cruddur-user-user-pool app Integration中进行了更改选择应用客户端托管UI
  • 托管的UI状态应为可用

Hosted UI Available

  • 将此行添加到.gitpod.yml文件中,以启用auto-redirect脚本在启动新工作区时自动运行:
source "$THEIA_WORKSPACE_ROOT/frontend-react-js/bin/auto-redirect"

添加Google登录按钮

我使用此reference使用Google按钮构建标志。根据您的需求随意修改它。

  • 将以下CSS添加到SigninPage.css
@import url(https://fonts.googleapis.com/css?family=Roboto:500);
 .google-btn {
  cursor:pointer;
     width: 184px;
     height: 42px;
     background-color: #4285f4;
     border-radius: 2px;
     box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .25);

}
 .google-btn .google-icon-wrapper {
     position: absolute;
     margin-top: 1px;
     margin-left: 1px;
     width: 40px;
     height: 40px;
     border-radius: 2px;
     background-color: #fff;
}
 .google-btn .google-icon {
     position: absolute;
     margin-top: 11px;
     margin-left: 11px;
     width: 18px;
     height: 18px;
}
 .google-btn .btn-text {
  cursor:pointer;
     float: right;
     margin: 11px 11px 0 0;
   background-color: transparent; 
   border: none;
     font-size: 14px;
     letter-spacing: 0.2px;
     font-family: "Roboto";
}
 .google-btn:hover {
     box-shadow: 0 0 6px #4285f4;
}
 .google-btn:active {
     background: #1669f2;
}
 .center-a-div {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300px;


 }
  • pages/SigninPage.js 中的表单的关闭标签下方添加JSX代码
<div className="center-a-div">
  <div className="google-btn" onClick={() => Auth.federatedSignIn({ provider: 'Google' })}>
    <div className="google-icon-wrapper">
      <img className="google-icon" src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg" />
    </div>
    <p class="btn-text"><b>Sign in with google</b></p>
  </div>
</div>
  • 这将创建一个“使用Google”按钮。

Google Login Button

收集访问令牌

  • 将此代码添加到pages/HomeFeedPage.js

const getIdToken = async () => {

    Auth.currentSession().then(res => {
      let accessToken = res.getAccessToken()

      localStorage.setItem(
        "access_token",
        accessToken.jwtToken
      );

      loadData();
      checkAuth();

    })
  }

  • 更新react.usefect对此:
React.useEffect(() => {
    //prevents double call
    if (dataFetchedRef.current) return;
    dataFetchedRef.current = true;

    getIdToken();

  }, []);

最后一步

确保 lambda触发代码中的参数作为列表/元组传递,而不是使用拆卸操作员,否则您可能会遇到某些问题。感谢Tornike#7640此提示。

cur.execute(sql, parameters)
  • localStorage.removeItem的顺序更改为components/ProfileInfo.js签名函数内执行的第一个代码。
const signOut = async () => {
    try {
      localStorage.removeItem("access_token");
      await Auth.signOut({ global: true });
      window.location.href = "/";
    } catch (error) {
      console.log("error signing out: ", error);
    }
  };

我在localStorage.remove删除时遇到注销问题。

最后,运行docker-compose up开始应用程序。单击“使用Google登录”按钮打开Goog​​le登录页面。登录后,您将被重定向到前端。

working gif

参考: