MSA를 구성해야 하는 프로젝트에서 인증을 해주려면 어떻게 해야할지 찾아보다 AWS에서 API Gateway를 사용하여 인증을 구현한 예제가 있어 정리했다.
제가 생각하는 플로우는 대략 이렇습니다.
Header에 Authorization이 없어도 JWT Token을 리턴해준다.Header에 Authorization을 함께 보낸다.먼저 Lambda함수를 Node.js로 작성하였습니다.
const jwtDecode = require('jwt-decode');
module.exports.verify = async (event, context) => {
const {awsRequestId} = context;
const {authorizationToken, methodArn} = event;
const headers = authorizationToken
const tokenDecode = jwtDecode(headers)
if(tokenDecode.exp*1000 > Date.now()){
return generateAllow(awsRequestId, methodArn)
}
return generateDeny(awsRequestId, methodArn)
};
const generateAllow = (principalId, resource) => {
return generatePolicy(principalId, 'Allow', resource);
};
const generateDeny = (principalId, resource) => {
console.log(`[auth.js] deny. principalId: ${principalId}, resource: ${resource}`);
return generatePolicy(principalId, 'Deny', resource);
};
const generatePolicy = (principalId, effect, resource) => {
const authResponse = {principalId};
if (effect && resource) {
const policyDocument = {};
policyDocument.Version = '2012-10-17';
policyDocument.Statement = [];
const statementOne = {};
statementOne.Action = 'execute-api:Invoke';
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
return authResponse;
};
AWS API Gateway 서비스에서 위에서 생성한 Lambda함수를 권한 부여자로 연결하여 생성합니다.
테스트를 진행하게 되면 유효한 JWT Token을 보냈을때 (Effect:Allow)
만료된 JWT Token을 보냈을때 (Effect:Deny)
이렇게 Response가 잘 나옵니다.
API Gateway에 리소스와 메소드를 생성하고 스테이지에 배포하면 API Gateway의 URL 주소가 나온다.
(당장 테스트 가능한 API가 없으면 json-server를 사용하여 REST API를 구축하고 ngrok을 사용하여 외부에 노출하여 테스트하면 된다.)
메서드 요청 -> 승인 부분에 위에서 생성한 권한 부여자를 등록해준다.
Postman으로 JWT Token이 없이 API Gateway에 요청을 보내면 아래와 같은 결과가 리턴된다.
이제 본인이 만든 서버로 로그인을 완료한 뒤 유효한 JWT Token을 Header에 Authorization값을 Bearer Token을 추가하여 요청을 보내면 아래와 같이 json-server의 응답이 정상적으로 리턴된다.
Kong API Gateway도 사용해보았지만 간단하게 사용할 수 있는 솔루션은 AWS API Gateway가 더 쉽고 간단한거같다.