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가 더 쉽고 간단한거같다.