本示例展示了如何使用AWSAmplify 库将 HTTP 请求发送到 AWSAPI Gateway实例,并使用 Cognito登录凭证进行身份验证。源代码可以在 GitHub 上找到,同时 YouTube 上有一个视频展示了如何将此代码部署到 AWS,包括 API Gateway、Cognito、Lambda 和 S3 的配置。
首先,需要从AWSAmplify 库导入 Amplify 和 Auth 类:
import Amplify, { Auth } from 'aws-amplify';
接下来,需要配置 Amplify 类以访问 Cognito 用户池。将从 URL 查询参数中获取这些信息,以使示例通用:
var urlParams = new URLSearchParams(window.location.search);
Amplify.configure({
Auth: {
region: 'us-east-1',
userPoolId: urlParams.get('poolId'),
userPoolWebClientId: urlParams.get('appId'),
}
});
在这里,执行初始登录。用户名和密码将发送到Cognito,使用 Auth.signin() 方法,响应将是成功或请求额外信息。在这里只捕获密码更改请求,因为 Cognito 服务强制通过AWSWeb 控制台创建的每个用户都必须更改初始密码。但是,可能需要响应包括电话号码、电子邮件地址、双因素认证令牌等其他情况。
async function signIn(username, password) {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
// 显示密码更改表单
} else {
displayTokens(user);
}
}
在 displayTokens() 函数中,获取用户会话,从中可以获取 ID 和访问令牌。这些令牌在调用 API Gateway 端点时发送在 Authorization 头中(通过 invokeURL 查询参数传递)。
function displayTokens(user) {
user.getSession((err, session) => {
accessToken.value = session.accessToken.jwtToken;
idToken.value = session.idToken.jwtToken;
fetch(urlParams.get('invokeURL') + '/test', {
headers: {
'Authorization': session.idToken.jwtToken
}
}).then(response => response.text()).then(text => apiCall.value = text);
});
}
最后一步是将事件处理程序连接到初始登录按钮的点击事件:
login.onclick = () => signIn(username.value, password.value);
<html>
<head>
</head>
<body>
<div id="initiallogin">
<label>Username</label>
<input id="username" type="text"/>
<label>Password</label>
<input id="password" type="text"/>
<input id="login" type="button" value="Login"/>
</div>
<div id="changepassword" style="display: none">
<label>New Password</label>
<input id="newpassword" type="text"/>
<input id="changepass" type="button" value="Change Password"/>
</div>
<div id="results" style="display: none">
<h3>ID Token</h3>
<textarea cols="100" id="idToken" readonly="true" rows="15"></textarea>
<h3>Access Token</h3>
<textarea cols="100" id="accessToken" readonly="true" rows="15"></textarea>
<h3>API Call Result</h3>
<textarea cols="100" id="apiCall" readonly="true" rows="15"></textarea>
</div>
<script src="main.js"></script>
</body>
</html>