从 JavaScript 调用 API Gateway/Cognito





5.00/5 (1投票)
了解如何从 JavaScript 客户端应用程序调用带 Cognito 凭据的 API Gateway。
引言
在本文中,我们将介绍一个简单的 JavaScript 应用程序,它可以利用 Cognito 登录的凭据向 AWS API Gateway 实例发出经过身份验证的 HTTP 请求。
背景
此示例项目的源代码可以在 GitHub 上找到。
此视频在 YouTube 上,展示了如何使用 API Gateway、Cognito、Lambda 和 S3 将此代码部署到 AWS 的屏幕录制。
Using the Code
我们首先从 AWS Amplify
库中导入 Amplify
和 Auth
类
import Amplify, {Auth} from 'aws-amplify';
Amplify
类需要配置 AWS 区域、Cognito 用户池 ID 和 Cognito 应用程序客户端 ID。 我们从 URL 查询参数获取这些信息,以使示例具有通用性。
/*
Configure the Amplify library with the details required to access a Cognito user pool
*/
var urlParams = new URLSearchParams(window.location.search);
Amplify.configure({
Auth: {
// Amazon Cognito Region
region: 'us-east-1',
// Amazon Cognito User Pool ID
userPoolId: urlParams.get('poolId'),
// Amazon Cognito Web Client ID (26-char alphanumeric string)
userPoolWebClientId: urlParams.get('appId'),
}
});
我们在这里执行初始登录。 用户名和密码通过 Auth.signin()
方法发送到 Cognito,响应将是成功,或请求其他信息。
我们仅捕获密码更改的请求,因为 Cognito 服务强制通过 AWS Web 控制台创建的每个用户都进入一种必须更改初始密码的状态。 但您可能需要响应许多其他情况,包括电话号码、电子邮件地址、双因素身份验证令牌等的请求。
登录或密码更改成功后,我们调用 displayTokens()
函数。
/**
* Attempt the initial login of a Cognito user. This may result in a password change
* form being displayed if required. Once logged in, the id and access tokens will
* be displayed.
* @param username The Cognito username
* @param password The Cognito password
*/
async function signIn(username, password) {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
initiallogin.style.display = "none";
changepassword.style.display = "";
changepass.onclick = async () => {
await Auth.completeNewPassword(
user,
newpassword.value
).then((user) => {
displayTokens(user);
});
};
} else {
displayTokens(user);
}
}
在 displayTokens()
函数中,我们获取用户会话,从中可以获取 ID 和访问令牌。 这些令牌在调用 API Gateway 端点时发送在 Authorization
标头中(通过 invokeURL
查询参数传入)。
重要的是要注意,即使 HTTP 规范规定您必须这样做,我们也不会在标头值中添加 bearer
前缀。 这是 API Gateway Cognito 授权器中的一个已知错误,即不支持此前缀。
/**
* Display the id and access tokens from the logged in Cognito user
* @param user The CognitoUser returned as a result of a successful login
*/
function displayTokens(user) {
initiallogin.style.display = "none";
changepassword.style.display = "none";
results.style.display = "";
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);
});
}
最后一步是将事件挂接到初始登录按钮单击。
/*
Attach an event handler to the login click event
*/
login.onclick = () => signIn(username.value, password.value);
这是显示登录表单的 HTML 页面
<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>
历史
- 2019 年 12 月 30 日 - 初始发布