本文基于Andrew Brown's AWS Cloud Project bootcamp中使用的CRUDDUR应用程序。
我已经实施了可能不是完美的解决方案,但它符合其目的。如果您有任何建议或遇到任何问题,请随时让我知道。
设置Google Auth提供商
- Go to Google developer console.
- 单击选择一个项目
- 单击新项目。
- 输入您的项目的名称,然后单击创建。
- 创建项目后,从左侧的“导航”菜单中选择 apis&emervice 。
- 接下来,单击凭据。
- 单击配置屏幕的同意。
- 接下来,单击创建。
- 输入应用程序信息的所需信息和开发人员联系信息字段,然后单击保存并继续 3次(OAuth同意屏幕 - >范围 - >测试用户)要完成同意屏幕设置。
- 在左侧导航菜单中,单击凭据 tab。
- 要创建您的OAuth 2.0凭据,请从创建凭据下拉列表中选择 oauth client ID 。
- 选择 Web Application 作为应用程序类型并将其命名为OAuth客户端。
- 单击创建。
- 记下您的客户ID 和您的客户秘密。您将需要下一节。
- 选择 ok 。
在您的用户池中添加社交IDP
- 转到Amazon Cognito console并选择用户池。
- 从列表中选择 cruddur-user-pool 用户池。
- 单击登录体验选项卡,然后找到联合登录。单击添加身份提供商。
- 选择 Google 作为您的社交IDP。
- 输入Google Developer Console App Client ID 和 App客户端秘密是在上一节中生成的。
- 对于授权范围,添加以下内容:
profile email openid
- 从您的IDP到用户池的地图属性。
用户池属性 | Google属性 |
---|---|
电子邮件 | 电子邮件 |
名称 | 名称 |
preferred_username | given_name |
用户名 | sub |
- 选择添加身份提供者。
- 从 app client Integration tab中,从列表中选择 app client ',单击 编辑托管托管UI设置。。
- 目前,为添加一个url
http://localhost:3000
允许的回调URLS 允许登录URL â(可选)。 - selectâ google 身份提供商菜单。
- 确保设置 oauth 2.0授予类型 n emnit grant 。这说明客户端应直接接收访问令牌(并且可以选择地,基于范围的ID令牌)。
有一个建议使用授权代码的选项,但是为了这样做,我们需要在后端中实现代码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。
- 在左导航栏上,选择凭据。
- 选择您在第一步中创建的客户端,然后单击“编辑”按钮。
- 在授权的JavaScript Origins 字段中,输入您的用户池域。
- 在授权重定向uris 字段中,使用
/oauth2/idpresponse
端点输入您的用户池域。
- 单击保存保存更改。
注意:如果您看到一条错误消息,该消息说“无效重定向:必须在提交端点之前添加到授权域列表中”,请添加端点时,请转到授权的域列表并添加域。更多信息:Social sign-in (OAuth)
测试您的社交IDP配置
- 返回到 cruddur-user-pool 控制台,从动作下拉列表下的域菜单中,选择创建cognito域。
- 输入独特的域前缀。
要查看托管的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时将显示的页面。
尝试使用此按钮签名。如果遇到任何错误,请确保正确遵循所有前面的步骤。
成功注册后,您将被重定向到 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状态应为可用。
- 将此行添加到
.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”按钮。
收集访问令牌
- 将此代码添加到
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登录”按钮打开Google登录页面。登录后,您将被重定向到前端。
参考:
- Cognito User Pools with Social Identity Providers
- Integrating Social Media to your App with AWS Cognito
- The Complete Guide to User Authentication with the Amplify Framework
- Amplify Authentication documentation
- Cognito User Pools App Integration
- Using Tokens with User Pools
- Cognito client is not enabled for OAuth2.0 flows
- How to Access Tokens on Successful Auth SignIn