IAM 인증으로 API Gateway에 연결하기
IAM 인증으로 API Gateway 연결하기
AWS IAM으로 보호된 API Gateway 엔드포인트에 연결하는 것은 까다로울 수 있습니다. Signature Version 4를 사용해 요청에 서명해야 합니다. 이를 위해 다음을 사용할 수 있습니다:
생성된 SDK는 변경이 있을 때마다 다시 생성해야 하기 때문에 사용하기 어려울 수 있습니다. 그리고 AWS Amplify 설정 챕터에서 AWS Amplify를 사용해 앱을 설정하는 방법을 다룹니다.
하지만 AWS JS SDK를 사용해 API Gateway에 간단히 연결하려는 경우, 독립적으로 사용할 수 있는 sigV4Client.js
를 만들었습니다. 이는 생성된 SDK에 미리 패키징된 클라이언트를 기반으로 합니다.
이번 챕터에서는 sigV4Client.js
를 사용하는 방법을 살펴보겠습니다. 기본적인 흐름은 다음과 같습니다:
- Cognito 사용자 풀로 사용자를 인증하고 사용자 토큰을 획득합니다.
- 사용자 토큰으로 Identity Pool에서 임시 IAM 자격 증명을 가져옵니다.
- IAM 자격 증명을 사용해 Signature Version 4로 API 요청에 서명합니다.
Cognito User Pool로 사용자 인증하기
다음 방법으로 Cognito User Pool에 사용자를 인증할 수 있습니다.
function login(username, password) {
const userPool = new CognitoUserPool({
UserPoolId: USER_POOL_ID,
ClientId: APP_CLIENT_ID,
});
const user = new CognitoUser({ Username: username, Pool: userPool });
const authenticationData = { Username: username, Password: password };
const authenticationDetails = new AuthenticationDetails(authenticationData);
return new Promise((resolve, reject) =>
user.authenticateUser(authenticationDetails, {
onSuccess: (result) => resolve(),
onFailure: (err) => reject(err),
})
);
}
USER_POOL_ID
와 APP_CLIENT_ID
를 사용해야 합니다. 그리고 사용자의 Cognito username
과 password
를 제공하면 다음과 같이 호출하여 사용자를 로그인할 수 있습니다.
await login("my_username", "my_password");
임시 IAM 자격 증명 생성하기
사용자가 인증되면 임시 자격 증명을 생성할 수 있습니다. 이를 위해 먼저 다음 코드를 사용하여 JWT 사용자 토큰을 가져와야 합니다:
function getUserToken(currentUser) {
return new Promise((resolve, reject) => {
currentUser.getSession(function (err, session) {
if (err) {
reject(err);
return;
}
resolve(session.getIdToken().getJwtToken());
});
});
}
현재 로그인한 사용자는 다음 코드로 가져올 수 있습니다:
function getCurrentUser() {
const userPool = new CognitoUserPool({
UserPoolId: config.cognito.USER_POOL_ID,
ClientId: config.cognito.APP_CLIENT_ID,
});
return userPool.getCurrentUser();
}
그리고 JWT 토큰을 사용하여 임시 IAM 자격 증명을 생성할 수 있습니다:
function getAwsCredentials(userToken) {
const authenticator = `cognito-idp.${config.cognito.REGION}.amazonaws.com/${config.cognito.USER_POOL_ID}`;
AWS.config.update({ region: config.cognito.REGION });
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: config.cognito.IDENTITY_POOL_ID,
Logins: {
[authenticator]: userToken,
},
});
return AWS.config.credentials.getPromise();
}
API Gateway 요청에 Signature Version 4로 서명하기
sigV4Client.js
를 사용하려면 crypto-js가 설치되어 있어야 합니다.
프로젝트 루트에서 다음 명령어를 실행하여 설치하세요.
$ npm install crypto-js --save
그리고 sigV4Client.js
를 사용하려면 해당 파일을 프로젝트로 복사하세요.
이 파일은 처음 보면 조금 복잡해 보일 수 있지만, 임시 자격 증명과 요청 파라미터를 사용해 필요한 서명된 헤더를 생성하는 역할을 합니다. 새로운 sigV4Client
를 생성하려면 다음과 같은 정보를 전달해야 합니다.
// 의사 코드
sigV4Client.newClient({
// AWS 임시 액세스 키
accessKey,
// AWS 임시 시크릿 키
secretKey,
// AWS 임시 세션 토큰
sessionToken,
// API Gateway 리전
region,
// API Gateway URL
endpoint,
});
요청에 서명하려면 signRequest
메서드를 사용하고 다음 정보를 전달해야 합니다.
// 의사 코드
const signedRequest = client.signRequest({
// HTTP 메서드
method,
// 요청 경로
path,
// 요청 헤더
headers,
// 요청 쿼리 파라미터
queryParams,
// 요청 본문
body,
});
signedRequest.headers
를 통해 요청에 필요한 서명된 헤더를 얻을 수 있습니다.
sigV4Client로 API Gateway 호출하기
이제 모든 것을 종합해 보겠습니다. 다음은 API Gateway 엔드포인트를 호출하기 위한 간단한 헬퍼 함수입니다.
function invokeApig({
path,
method = "GET",
headers = {},
queryParams = {},
body
}) {
const currentUser = getCurrentUser();
const userToken = await getUserToken(currentUser);
await getAwsCredentials(userToken);
const signedRequest = sigV4Client
.newClient({
accessKey: AWS.config.credentials.accessKeyId,
secretKey: AWS.config.credentials.secretAccessKey,
sessionToken: AWS.config.credentials.sessionToken,
region: YOUR_API_GATEWAY_REGION,
endpoint: YOUR_API_GATEWAY_URL
})
.signRequest({
method,
path,
headers,
queryParams,
body
});
body = body ? JSON.stringify(body) : body;
headers = signedRequest.headers;
const results = await fetch(signedRequest.url, {
method,
headers,
body
});
if (results.status !== 200) {
throw new Error(await results.text());
}
return results.json();
}
YOUR_API_GATEWAY_URL
과 YOUR_API_GATEWAY_REGION
을 반드시 교체해야 합니다. 질문이 있으면 댓글로 남겨주세요.
For help and discussion
Comments on this chapter